【问题标题】:Closing all pipes of a process关闭进程的所有管道
【发布时间】:2016-03-25 15:05:43
【问题描述】:

我正在制作一个程序,它的行为方式与 shell 类似,但只支持前台进程和管道。我有多个进程写入同一个管道以及与管道的正常使用不同的一些其他属性。无论如何,我的问题是,

除了三个基本文件描述符之外,还有什么简单(自动)的方法可以关闭进程的所有文件描述符?

我问这个问题是因为我很难跟踪每个进程的所有文件描述符。有时他们会以一些不可预知的方式行事。也可能是因为我对它们的了解不是很透彻。

【问题讨论】:

  • shell 脚本还是 C?
  • 很抱歉我忘了提。它是 C++。
  • 添加您的代码摘录...
  • 您应该真正了解如何跟踪正在使用的文件描述符。您可以在fcntl() 中查找FD_CLOEXEC 参数,并且某些系统允许open() 上的O_CLOEXEC。但是,要应用它,您需要知道文件描述符,以便确保当您的进程执行另一个程序时它会自动关闭。但是,这可能不是您的问题。

标签: shell pipe c++ fork


【解决方案1】:

除了三个基本文件描述符之外,有没有简单的方法(自动)关闭进程的所有文件描述符?

执行此操作的正常方法是简单地遍历所有它们并关闭它们:

for (i = getdtablesize(); i > 3;) close(--i);

这已经是一条线了。没有比这更“自动”的了。

我问这个问题是因为我很难跟踪每个进程的所有文件描述符。

值得您花时间考虑您打开的每个文件描述符的生命周期、何时重复(例如dup2()fork())、如何使用它,并确保您考虑每个文件描述符的使用方式当不再需要它时,它会被关闭。通过不加选择地关闭所有文件描述符来解决泄漏文件描述符的问题是不可持续的。

我有多个进程写入同一个管道

如果您这样做,那么您需要注意数据到达管道另一端的顺序是不可预测的。很难避免破坏数据流。

【讨论】:

  • 感谢您的回答。我通过以另一种方式关闭所有不必要的文件描述符来解决我的问题,但我会记下这一点,以防我以后需要它。
  • 注意:POSIX 说应该使用sysconf(_SC_OPEN_MAX) 而不是getdtablesize(),这是非标准的。
【解决方案2】:

使用closefrom(3) C 库函数。

来自手册页:

closefrom() 系统调用删除所有打开的文件描述符 大于或等于每个进程对象引用表中的 lowfd。 关闭文件描述符时遇到的任何错误都会被忽略。

示例用法:

#include <unistd.h>

int main() {
    // Close everything except stdin, stdout and stderr
    closefrom(3); // Were 3 is the lowest file descriptor you wish to close

    printf("Clear of all, but the three basic file descriptors!\n");
    return 0;
}

这适用于大多数 unice,但需要 Linux 的 libbsd 支持库

【讨论】:

  • 你能提供一个网址吗? Linux有哪些亚种?我在linux.die.net 找不到它,我通常去那里查找 Linux 手册页。
  • @Lonathan Leffler 你说得对,在 Linux 上它实际上只在 libbsd 中可用(BSD 系统中的实用程序函数“)。只有 *everything else Unixy 有这个作为本机系统或库调用。
  • 嗯;我想知道Mac OS X 是否是Unixy; 10.11.4 El Capitan 似乎没有它(因为它是一个基于 BSD 的库)。 OTOH,Solaris 10 有它(标题 &lt;stdlib.h&gt;),但 HP-UX 11.23 没有,AIX 6.3 没有。当然,HP 和 IBM 版本不是最新的。
  • 对于 Linux,一个名为 close_range 的系统调用已在 5.9 中合并,因此希望此功能最终会出现在 glibc 和朋友中:lwn.net/Articles/837816
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-08
  • 1970-01-01
  • 2020-04-10
  • 1970-01-01
相关资源
最近更新 更多