我正在创建一个TCP服务,该服务在每次客户端连接时分叉一个新进程。在分叉之前,我设置了一个管道,以便子级可以将连接期间收集的统计信息发送回父级。父项关闭写入端,子项关闭读取端,父项维护读取端文件描述符数组,每个子项一个。
我不确定当孩子完成连接并退出时如何处理这些文件描述符。子级是否需要通过管道通知父级即将退出,以便父级可以关闭管道?或者,父级能否在子级退出并关闭后自动检测到管路损坏?
父程序中的代码正在运行一个循环,其中< code>select()检测监听套接字和子管道读取端的活动。每个子进程可以在运行时向父进程发送多条消息。
一般来说,当子进程退出时,父进程应该如何处理管道文件描述符?
< code>broken pipe发生在您写入管道,但没有打开fd从该管道读取时。所以不适用于你的情况。在您的情况下,由于您的父进程正在从管道中读取,当子进程退出时,它应该读取< code>EOF(如果您已经正确地关闭了父进程中的写入端,否则它将只是阻塞,因为它假定将来仍会有要读取的内容)。然后,您可以安全地关闭父进程中的read fd。
总的来说
如果父进程写而子进程读,你确实需要担心< code>broken pipe,即当子进程关闭read fd时,父进程得到SIGPIPE,因为它继续写管道。SIGPIPE默认终止进程,所以您可能希望设置一个信号处理程序,让它做您想做的任何事情(如果您不希望它只是终止)。
在您的情况下,父进程将在fork之后立即关闭管道的写入端。然后它可以读取其统计数据,直到EOF(文件结束),然后关闭管道的读取端。
第一遍:在清楚使用select()
存在循环并且孩子发送了多条消息之前。
如果父进程维护一个文件描述符数组,则它还需要将每个文件描述符与子进程相关联。如果孩子在死亡之前发送了一条小的统计消息,那么当主程序等待死去的孩子时,它知道哪个孩子死了,所以它可以关闭它刚刚发现的死亡的孩子的文件描述符(通过执行一次或多次最终读取来确保管道是空的)。
另一种机制使用select()
或()
或相关函数,该函数会报告对文件描述符的读取操作何时不会挂起。当它从管道中检测到EOF(读取的零字节)时,它知道孩子已经死亡。但是,这可能更难处理。
您的问题并不完全清楚,当子进程退出时,是否有来自它的单一消息,或者当子进程工作时,是否有“意识流”统计报告。如果只有一条消息(小于管道缓冲区的大小),那就简单了。如果有一个消息流,或者消息的长度超过了管道缓冲区的大小,那么您必须更加仔细地考虑协调问题——您不能只在孩子死亡时才检测消息。
第二遍:在额外信息可用之后。
如果你已经在循环中使用 select(),
那么当一个孩子死亡时,你将从 select()
获得一个“管道准备读取”指示,并且你将从 read()
获得 0 个字节,这表示该管道上的 EOF。然后你应该关闭那个管道(并等待一个或多个带有waitpid()
的孩子,可能使用W_NOHANG
- 应该至少有一具尸体被收集 - 所以你不会让僵尸长时间踢来踢去)。
最后一个问题的严格答案是:当唯一具有管道写入端的子级死亡时,父级应关闭该管道的读取端以释放资源以供以后重用。
问题内容: 我正在使用ProcessBuilder启动子进程,并且如果父进程确实需要退出子进程。在正常情况下,我的代码可以正确阻止孩子。但是,如果我导致操作系统杀死父进程,则子进程将继续运行。 有什么方法可以将子进程“绑定”到父进程,以便在父进程被杀死时退出? 问题答案: 子进程与其父进程之间没有联系。他们可能彼此知道进程ID,但是它们之间没有硬连接。您在谈论孤立过程。这是操作系统级别的问题。意味
问题内容: 我想使用模块来完成此操作。 当我这样做时,例如: 我启动一个父进程,然后让父进程产生一个子进程, 然后我希望父进程退出自身,但子进程继续工作。 请允许我写一个 错误 代码来解释一下自己: 那么,我如何启动一个在父进程完成时不会被杀死的进程? 20140714 大家好 我的朋友刚刚告诉我一个解决方案… 我只是想… 无论如何,只要让您看到: 这确实有效!! 问题答案: 一个技巧:调用以退出
问题内容: 假设我有一个进程,它恰好产生了一个子进程。现在,当父进程出于某种原因(正常或异常,通过kill,^ C,断言失败或其他任何原因)退出时,我希望子进程死亡。如何正确地做到这一点? 问题答案: 子进程可以通过在syscall中指定选项来要求父进程去世时内核发出(或其他信号),如下所示: 有关详细信息,请参见。 编辑:这是仅Linux
Process 结构体代表了一个正在运行的子进程,并公开了stdin(标准输入),stdout(标准输出) 和 stderr(标准错误) 句柄,通过管道和底层的进程交互。(原文:The Process struct represents a running child process, and exposes the stdin, stdout and stderr handles for int
问题内容: 对于子进程,和函数可用于暂停当前进程的执行,直到子进程退出。但是此功能不能用于非子进程。 是否有另一个函数可以等待任何进程的退出? 问题答案: 什么都不等于。通常的做法是使用轮询,寻找返回值-1和的,表明进程已经一去不复返了。
问题内容: 是否可以从Shell脚本中的父进程ID获取子进程ID? 我有一个要使用Shell脚本执行的文件,这会导致一个新进程 process1 (父进程)。这个 过程1 已经分叉的另一个进程 过程2 (子进程)。使用脚本,我可以使用以下命令获取 process1 的pid : 但我无法获取子进程的pid。 问题答案: 只需使用: