2

我跟踪了一个oracle进程,发现它首先打开一个文件/etc/netconfig作为文件句柄11,然后通过使用参数256调用复制它,然后是原始文件句柄。后来它使用文件句柄读取。那么复制文件句柄有什么意义呢?为什么不只处理原始文件句柄?fcntlF_DUPFDclose11256

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
4

3 回答 3

6

在某些系统上,如 Solaris,标准 I/OFILE仅适用于文件描述符 0-255,因为其FILE结构的实现使用 8 位整数而不是 int。如果程序使用大量文件描述符,则使用 . 保留文件描述符 3-255 很有用fnctl(fd, F_DUPFD, 256)。否则,如果您打开了 256 个文件,类似fopen(),freopen()和的函数将失败。fdopen()

于 2011-01-07T15:02:10.617 回答
5

顺便说一句,它们是文件描述符而不是文件句柄。后者是fopen与它的兄弟一起使用的 C 功能,而描述符则更 UNIXy,用于与openet al 一起使用。

有趣的。想到的唯一原因是其他一些代码特别需要文件描述符为 256。我怀疑只有 Oracle 会知道其中的奇怪原因。无论如何,你不能保证得到 256,你得到的文件第一个可用的文件描述符大于或等于那个数字。


通过一些调查(我不知道关于 UNIX 内部的一件小事),有些属性属于一组重复的描述符,例如文件位置和访问模式。还有其他属性属于单个文件描述符,即使是重复的,例如 GNULib 中的 close-on-exec 标志。

进行复制(使用dupdup2您的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

也许软件在某个地方有一个文件描述符字节数组,因此它会尝试将其他文件移动到 255 限制以上。

但实际上,这只是我的猜测(尽管我想认为这是相对明智的猜测)。还要记住,这可能不是 Oracle 自己做的。netconfig 的东西在很多地方都用到了,所以它可能是一些底层库在做这件事,特别是考虑到大多数上述网络点击都不是 Oracle 特定的(ftp等等remsh)。

于 2010-04-12T03:47:10.197 回答
2

这是另一个需要保留低编号文件描述符的技术的示例。

假设一个进程打开了大量的文件描述符,例如它同时接受超过 1024 个套接字连接。同时,该进程还使用第三方库打开套接字连接并用于select()查看套接字是否准备好进行读取或写入。此外,第三方库编译时__FD_SETSIZE设置为 1024(默认值)。

如果库在使用低于 1024 的所有文件描述符时打开一个套接字,那么它将获得一个描述符select()和相关的 FD_* 宏无法处理。这将导致进程崩溃或未定义的行为。

于 2014-02-14T11:54:47.703 回答