【发布时间】:2019-01-07 11:54:31
【问题描述】:
我对创建和获取子进程有一些疑问。
第一季度。为什么Linux会自动reap子进程让程序员不用使用waitpid(),从而减少了程序员的工作量?
第二季度。创建子进程并让子进程执行程序有什么好处,例如Web 服务器调用 fork 创建子进程并调用 execve 运行 cgi 程序?不能让父进程运行cgi程序吗?
【问题讨论】:
我对创建和获取子进程有一些疑问。
第一季度。为什么Linux会自动reap子进程让程序员不用使用waitpid(),从而减少了程序员的工作量?
第二季度。创建子进程并让子进程执行程序有什么好处,例如Web 服务器调用 fork 创建子进程并调用 execve 运行 cgi 程序?不能让父进程运行cgi程序吗?
【问题讨论】:
Linux 不会自动获取进程,因为您可能希望派生一个子进程并终止父进程,即守护进程。您还需要一种方法来获取子进程的退出代码,没有这种机制就无法获取它。如果您不想等待子进程,请在启动应用程序时调用 signal(SIGCHLD, SIG_IGN);,然后再分叉任何子进程。
对于记录窗口具有相同的使用模式,调用WaitForSingleObject 以等待子线程终止,您可以省略它,但这样做是非常糟糕的做法,因为它会使句柄和返回代码挂在内存中。
除非您使用多线程,否则父进程一次不能执行多个任务。 Fork 一个子进程来处理传入的请求,可以让你异步处理多个请求,例如:https://jameshfisher.com/2017/02/25/tcp-server-fork.html
【讨论】:
第一季度。 Linux(或一般的 UNIX)仅在父进程在子进程之前死亡时才获取子进程。在这种情况下,内核让一些实现定义的进程(以前是init 进程)采用孤立进程。然后这个新的父进程将对进程状态变化做出反应。
第二季度。每个进程分叉和处理一个任务是并行处理几个任务的一种方式。根据您的要求,这通常会导致比在一个进程中处理多个任务更简单的代码。在某些情况下,这是唯一可行的方法。使用线程是一个类似的解决方案。一个不同的解决方案是在所有可能阻塞的呼叫之前使用select,并确保您一个接一个地处理每个任务。
运行 CGI 程序意味着您必须运行脚本解释器。如果您自己不实现解释器,这意味着您必须运行一个难以控制的单独程序。当脚本需要很长时间或由于某种原因阻塞时,您不想阻塞所有其他任务。因此,与在父进程或其他子进程中接受和处理请求并行运行它更容易在子进程中运行。 在这种情况下,很难或通常不可能阻止单独的程序阻塞其他任务,因此最好在子进程中执行此操作。
【讨论】: