【发布时间】:2015-06-12 19:22:16
【问题描述】:
我有一个从标准输入读取的程序,在执行此操作时,它有时需要 fork() 并异步执行命令。有时在此分叉后不久(可能在命令运行时),父级似乎丢失了从标准输入读取的数据。如果只丢失一个字节,程序将永远无法恢复。
fork() 的手册页说子进程继承了父进程的打开文件描述符集的副本,但是在 fork() 之后和 execvp() 之前尝试 close(STDIN_FILENO) 没有帮助。
我的程序基本上是这样的:
if (we_need_to_run_a_command_asynchronously) {
if (!fork()) {
close(STDIN_FILENO);
char *args[] = { "command", "arg", "etc", 0 };
setpriority(PRIO_PROCESS, 0, -19);
execvp("command", args);
exit(0); // Ignore errors
}
}
如何确保孩子不会干扰父母的标准输入(或其他任何属于父母的东西)?执行的命令通常是一个 shell 脚本。
我不知道我的程序到底出了什么问题,但只要它不运行任何命令,它就可以正常运行。只有有时(并非总是)在它运行命令之后,它从标准输入读取的数据以某种方式被破坏,这就是为什么我怀疑问题与 fork() 之后的标准输入有关。
【问题讨论】:
-
您能否通过编写两个小型测试程序来检验您的假设,一个从标准输入读取,一个不读取,然后让您的父程序执行这些程序,看看会发生什么?
-
请分享一个可编译的小程序。它可以帮助我们进入它
-
您可以为标准输入设置 close-on-exec 标志,而不是显式关闭。但是,问题可能有不同的原因(演示问题的简短示例程序可能会有所帮助)。
-
也许可以产生一个 pthread 而不是一个新进程?
-
您执行的命令有权打开标准输入。你可以给它
/dev/null来阅读。您对command了解多少(除了名称command是一个内置的shell)?你写了吗?它是从什么读来的?基本上,如果您将其标准输入连接到/dev/null,您应该不会看到问题。