【问题标题】:Is there a system call or some way to know the type of file descriptor in Linux (e.g. regular file fd, socket fd, signal fd, timer fd)?是否有系统调用或某种方式可以知道 Linux 中文件描述符的类型(例如常规文件 fd、套接字 fd、信号 fd、计时器 fd)?
【发布时间】:2020-02-25 17:53:38
【问题描述】:

正如我不断发现的那样,有各种各样的文件描述符 - 几乎所有东西都围绕文件描述符进行抽象:常规文件、套接字、信号和计时器(例如)。所有文件描述符都只是整数。

给定一个文件描述符,是否有可能知道它是什么类型?例如,最好有一个系统调用,例如 getFdType(fd)。

如果由于多个文件描述符准备就绪而唤醒了 epoll_wait,则每个文件描述符的处理将基于其类型。这就是我需要类型的原因。

当然,我可以自己单独维护这些信息,但让系统支持会更方便。

此外,所有文件描述符,无论类型如何,都是顺序的。我的意思是如果你打开一个常规的数据文件,然后创建一个计时器文件描述符,然后一个信号文件描述符,它们都保证按顺序编号吗?

【问题讨论】:

  • 最好问一下,例如出于调试/分析原因检查任意 FD,而不是将其用于 epoll 决策,因为这是一个限制性的设计决策和架构死胡同。 AFAIK 没有像 getFdType 这样的东西,但传统上一直有 fstat 来区分类似文件的类型,并尝试像 getsockopttimerfd_gettime 这样的 fd 特定调用来区分这些,作为最后的手段,readlink on @ 987654327@ 获取描述性字符串,如anon_inode:[timerfd]
  • 这是 fstat 调用。 linux.die.net/man/2/fstat
  • @thatotherguy “......因为这是一个限制性的设计决策和架构死胡同。”你能详细说明吗?如果需要,我对架构更改持开放态度。
  • 无论如何,大多数服务器都需要为每个 FD 提供额外的上下文和元数据,例如其当前协议特定的状态/标志、发送/接收队列或位置、水印/重试信息等。
  • @thatotherguy 我已经解决了这方面的问题。我的 fdData 结构维护这样的信息。我认为 Nate 观察到使用系统调用(如果可用)会很昂贵,这是我没有想到的。

标签: linux sockets timer signals epoll


【解决方案1】:

正如“那个人”所提到的,最明显的这样的电话是fstatst_mode 成员包含用于区分常规文件、设备、套接字、管道等的位。

但在实践中,您几乎肯定需要自己跟踪哪个 fd 是哪个。当您打开几个不同的常规文件时,知道它是一个常规文件并没有太大帮助。因此,既然您无论如何都必须在代码中的某处维护这些信息,那么引用该记录似乎是最可靠的方法。

(检查程序中的一些变量也比进行一个或多个额外的系统调用要快得多。)

此外,所有文件描述符,无论类型如何,都是顺序的。我的意思是如果你打开一个常规的数据文件,然后创建一个计时器文件描述符,然后一个信号文件描述符,它们都保证按顺序编号吗?

不是真的。

据我所知,创建新 fd 的调用将始终返回编号最小的可用 fd。有一些旧程序依赖于这种行为;在dup2 存在之前,我相信将标准输入移动到新文件的公认方法是close(0); open("myfile", ...);

但是,很难确定哪些 fds 可用。例如,用户可能以/usr/bin/prog 5>/some/file/somewhere 运行您的程序,然后会出现 fd 5 被跳过,因为/some/file/somewhere 已经在 fd 5 上打开。因此,如果您连续打开一堆文件,您不能确定您是否会获得连续的 fd,除非您自己刚刚关闭了所有这些 fd,并且确定所有编号较低的 fd 都已在使用中。这样做似乎比一开始就跟踪 fd 更麻烦(也是潜在问题的根源)。

【讨论】:

  • “(检查程序中的一些变量也比进行一个或几个额外的系统调用要快得多。)”恕我直言,您回答的关键点。
  • 好吧,我不想做太多的事情,因为在许多程序中,无论哪种方式,它都只是总执行时间的一小部分。但我想我会投入一些东西来吸引那些无法抗拒不必要的优化的人;-)
猜你喜欢
  • 2015-04-14
  • 2015-01-04
  • 1970-01-01
  • 1970-01-01
  • 2023-01-19
  • 1970-01-01
  • 2018-07-22
  • 2017-03-31
  • 1970-01-01
相关资源
最近更新 更多