gpt4 book ai didi

sockets - 如果关闭被中断或失败,fd的状态是什么?

转载 作者:行者123 更新时间:2023-12-03 12:06:30 27 4
gpt4 key购买 nike

读取手册页以关闭,如果它被信号打断,则未指定fd的状态。是否有处理这种情况的最佳实践,还是此后假设它成为操作系统的问题。

我认为EIO适当关闭fd之后会失败。

最佳答案

如果您希望程序长时间运行,可能的文件描述符泄漏绝不仅仅是操作系统的问题。不使用许多文件描述符的短期程序当然可以选择终止未关闭的描述符,并依赖内核在程序终止时将其关闭。因此,对于我的其余回答,我将假定您的程序正在长时间运行。

如果您的程序不是多线程的,则情况很简单:

int close_some_fd(int fd, int *was_interrupted) {
*was_interrupted = 0;
/* this is point X to which I will draw your attention later. */
for (;;) {
if (0 == close(fd))
return 0; /* Success. */
if (EIO != errno)
return -1; /* Some failure, not interrupted by a signal. */

/* Our close attempt was interrupted. */
*was_interrupted = 1;
int fdflags = 0;
/* Just use the fd to find out if it is still open. */
if (0 != fcntl(fd, F_GETFD, &fdflags))
return 0; /* Interrupted, but file is also closed. So we are done. */
}
}

另一方面,如果您的代码是多线程的,则其他某个线程(也许是您无法控制的线程,例如名称服务缓存)可能调用了 dupdup2socketopenaccept或其他一些类似的函数使内核分配文件描述符。

为了使类似的方法在这样的环境中起作用,您将需要能够分辨出开始使用的文件描述符和另一个线程新打开的文件描述符之间的区别。知道已经有一个编号较低的fd仍未打开,足以抵消其中的不足,但是在多线程环境中,您没有一种简单的方法来确定情况仍然如此。

一种选择是依赖某个通用方面来依赖程序使用的所有文件描述符。例如,如果它从不使用 O_CLOEXEC,则可以使用 fcntl在代码中标记为 X的点处设置O_CLOEXEC标志,然后将现有调用更改为 fcntl,如下所示:
    if (0 = fcntl(fd, F_GETFD, &fdflags)) {
if (fdflags & O_CLOEXEC) {
/* open, and still marked with O_CLOEXEC, unused elsewhere. */
continue;
} else {
return 0; /* Interrupted, but file is also closed. So we are done. */
}
}

您可以调整此方法以使用 O_CLOEXEC以外的其他功能(例如,也许 fstat记录 st_devst_ino),但是如果您不确定多线程程序的其余部分正在做什么,则此一般想法可能会令人不满意。

还有另一种方法也有问题,但可能有用。就是说,不是关闭文件描述符,而是使用 sendmsg将文件描述符跨Unix域套接字传递到单独的单线程专用服务器,该服务器的唯一工作就是关闭文件描述符。是的,这有点令人讨厌。这种方法的一些有趣之处在于:
  • 为了避免不确定您的fd是否确实传递到服务器并成功关闭,您可能应该从服务器返回的fd-closed-OK消息的返回 channel 中进行读取。这样也避免了在执行sendmsg时也需要阻止信号传递。但是,这意味着每个文件描述符关闭都会占用用户空间上下文切换开销(除非您将它们分批分配以分摊成本)。您需要避免线程A可能正在读取与线程B发出的请求相对应的fd-closed-OK报告的情况。您可以通过序列化关闭操作(这将限制性能)或对响应进行多路分解(即复杂的)。或者,您可以使用其他一些IPC机制来避免进行序列化或多路分解(例如,SYSV信号量)。
  • 对于大容量的过程,这将给内核的文件描述符垃圾收集器设备带来令人生厌的高负载,该负载通常不会受到很大的压力,因此可能会给您带来一些有趣的症状。

  • 至于我将在最经常使用的应用程序中亲自做的事情,我想出了可以在多大程度上假设我要关闭哪种文件描述符。例如,如果它们通常是套接字,那么我将使用测试程序进行尝试,并确定 EIO是否通常使文件描述符保持关闭状态。也就是说,确定 EIO上文件描述符的理论上未指定的状态在实践中是否可预测。如果fd可以是任何东西(例如磁盘文件,套接字,tty等),这将无法正常工作。当然,如果您使用的是某些开源操作系统,则可能只能够读取内核源代码并确定可能的结果。

    当然,在担心分片fd-close服务器以扩展fd-closes之前,我会尝试上述基于实验的系统。

    关于sockets - 如果关闭被中断或失败,fd的状态是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6707484/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com