我跟踪了一个oracle进程,发现它首先打开一个文件/etc/netconfig作为文件句柄11,然后256通过调用fcntl参数复制它F_DUPFD,然后close是原始文件句柄11.后来它使用文件句柄读取256.那么复制文件句柄有什么意义呢?为什么不只是处理原始文件句柄?
12931: 0.0006 open("/etc/netconfig", O_RDONLY|O_LARGEFILE) = 11
12931: 0.0002 fcntl(11, F_DUPFD, 0x00000100) = 256
12931: 0.0001 close(11) = 0
12931: 0.0002 read(256, " # p r a g m a i d e n".., 1024) = 1024
12931: 0.0003 read(256, " t s t p i _ c".., 1024) = 215
12931: 0.0002 read(256, 0x106957054, 1024) = 0
12931: 0.0001 lseek(256, 0, SEEK_SET) = 0
12931: 0.0002 read(256, " # p r a g m a i d e n".., 1024) = 1024
12931: 0.0003 read(256, " t s t p i _ c".., 1024) = 215
12931: 0.0003 read(256, 0x106957054, 1024) = 0
12931: 0.0001 close(256) = 0
Run Code Online (Sandbox Code Playgroud)
顺便说一句,它们是文件描述符而不是文件句柄。后者是C的功能fopen,它与brethren一起使用,而描述符则更多地是UNIXy,与openet al 一起使用。
有趣。我想到的唯一原因是,其他一些代码对文件描述符的特定需求是256。我怀疑只有Oracle会知道这种奇怪的原因。在任何情况下,都不能保证获得256,而是获得大于或等于该数字的文件首个可用文件描述符。
从位调查的(我不知道每一个关于UNIX的把我的头顶部的内脏小东西),还有一些属于一组重复的描述符的属性,如文件位置和访问模式。还有其他属性属于单个文件描述符,即使被复制也是如此,例如GNULib中的执行时关闭标志。
做一个重复的(要么dup,dup2或者你fcntl)可以创建两个描述符,一个不同的文件描述符属性的方式,但我看不到是因为第一个描述符被关闭,反正你的问题的情况下。如您所说,为什么不只使用低描述符?
有趣的是,如果您搜索netconfig f_dupfd,则会在fcntl失败的地方看到类似的痕迹,并且它将继续使用低描述符来读取该文件,因此我对此事的想法是,这是尝试尽可能保留低文件描述符。例如:
4327: open("/etc/netconfig", O_RDONLY|O_LARGEFILE) = 4
4327: fcntl(4, F_DUPFD, 0x00000100) Err#22 EINVAL
4327: read(4, " # p r a g m a i d e n".., 1024) = 1024
4327: read(4, " t s t p i _ c".., 1024) = 215
4327: read(4, 0x00296B80, 1024) = 0
4327: lseek(4, 0, SEEK_SET) = 0
4327: read(4, " # p r a g m a i d e n".., 1024) = 1024
4327: read(4, " t s t p i _ c".., 1024) = 215
4327: read(4, 0x00296B80, 1024) = 0
4327: close(4) = 0
Run Code Online (Sandbox Code Playgroud)
也许该软件在某个受限的地方有一个文件描述符的字节数组,因此它尝试将其他文件移到255个限制以上。
但是,实际上,这只是我的猜测(尽管我想认为这是相对明智的猜测)。还请记住,这可能不是Oracle本身执行的。访问netconfig东西在很多地方使用,因此它可能是一些底层库这样做,尤其是因为事实上,大部分前面提到的网络点击率不是Oracle特有的(ftp,remsh等等)。
小智 5
在某些系统(如Solaris)上,带有FILE的标准I/O仅适用于文件描述符0-255,因为它的FILE结构实现使用的是8位整数而不是int.如果程序使用大量文件描述符,则使用fnctl(fd,F_DUPFD,256)保留文件描述符3-255很有用.否则,如果打开256个文件,fopen(),freopen()和fdopen()等函数将失败.