【问题标题】:What is the compelling use case for the FD_CLOEXEC flag?FD_CLOEXEC 标志的引人注目的用例是什么?
【发布时间】:2018-01-05 08:39:10
【问题描述】:

我刚刚读到这个:

What does the FD_CLOEXEC fcntl() flag do?

我了解FD_CLOEXEC 的作用,但不知道为什么它很重要。为什么不在exec()ing 之前关闭所有相关的文件描述符?为什么设置FD_CLOEXEC 如此重要以至于可以设置一个特殊的O_CLOEXEC 开放模式标志(在Linux 2.6.something 及更高版本上),只是为了避免一点线程间同步?

【问题讨论】:

  • 因为(例如)在编写代码的 exec 部分时,您可能不知道当前使用的每个文件描述符?
  • @Jean-BaptisteYunès:操作系统提供这些功能仅仅是因为进程不必费心控制它们的线程?我不知道,不知何故听起来没有说服力。
  • 这与线程无关,只是进程管理。文件描述符是通过exec继承的,你可能在打开文件的时候不需要它,所以使用FD_CLOEXEC不要把负担放在谁编写代码的执行部分。
  • @Jean-BaptisteYunès:所以只需关闭所有您不信任的文件描述符以保持打开状态。
  • 再一次,为什么你认为你总是知道在你试图执行的时候分配了哪些描述符?

标签: linux unix fopen fcntl


【解决方案1】:

我有一个用例,尽管它来自一个玩具程序(实际上是一个家庭作业)。

任务是编写一个带有两个参数的程序,它们是可执行文件的名称。它将使用forkexec(或例如execve)启动它们,第一个程序的stdout 写入管道的一端,该管道的一端被读取为第二个程序的stdin

示例用法:./mypipeprogram ./program1 ./program2 应该给出与./program1 | ./program2 相同的结果。

我希望我的程序尽可能地接近防弹,这意味着我可以尽可能优雅地处理所有错误。

请原谅我,因为我认为我已经没有来源了,所以这是凭记忆。

我不得不尝试处理的一种错误是列出的程序之一不能是exec'd,但另一个可以。在这种情况下,不能exec 的进程可以kill 另一个进程,所以它不会永远挂起,或类似的事情。

事后看来,这可能不是最好的主意,因为关闭管道应该可以正常工作。

尽管如此,走一条路(我认为这是第一个进程,输出一个),我可以捕捉到这个,而不是 kill 另一个进程,甚至在它尝试 exec 另一个程序之前。

我所做的是打开另一个管道,并使用 FD_CLOEXEC 打开另一个管道,并使用 fnctl,依靠 POSIX 说“文件应在成功执行其中一个 exec 函数后关闭。”

然后第二个进程将准备到exec,从那个管道读取,当它关闭时,它会知道第一个进程成功exec'd,所以它可以继续。如果第一个进程的exec失败了,管道仍然是打开的,所以第二个进程在读取时仍然会被阻塞,第一个进程可以kill它。

TL;DR

我在管道上使用了FD_CLOEXEC,以允许一个进程等待第二个进程成功exec,或者如果exec 失败,则由第二个进程获得killed。

【讨论】:

    猜你喜欢
    • 2011-09-01
    • 2019-01-02
    • 2023-02-20
    • 2019-06-07
    • 1970-01-01
    • 2019-07-18
    • 1970-01-01
    • 1970-01-01
    • 2016-06-26
    相关资源
    最近更新 更多