使用waitpid函数或sigaction的? [英] Using waitpid or sigaction?

查看:162
本文介绍了使用waitpid函数或sigaction的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经认识到:
1)waitpid函数用于等待一个孩子的死亡,然后收集SIGCHLD和孩子的退出状态等。
2)当我们有一个SIGCHLD信号处理程序,我们做了一些有关儿童或其他的东西(高达程序员的清理更多的东西),然后做一个waitpid函数这样孩子不会去僵尸,然后返回。

I have understood that: 1) waitpid is used to wait for a child's death and then collect the SIGCHLD and the exit status of the child etc. 2) When we have a signal handler for SIGCHLD, we do some more things related to cleanup of child or other stuff (upto the programmer) and then do a waitpid so that the child will not go zombie and then return.

现在,我们需要在我们的节目或1和2,当我们做一个叉/ exec和孩子的回报?
如果我们同时拥有,首先获得了SIGCHLD,所以信号处理程序被调用第一,因此,其waitpid函数调用成功,而不是在父进程code中的waitpid函数如下:

Now, do we need to have both 1 and 2 in our programs when we do a fork/exec and the child returns ? If we have both, the SIGCHLD is obtained first, so the signal handler is called first and thus its waitpid is called successfully and not the waitpid in the parent process code as follows:

my_signal_handler_for_sigchld
{
do something
tmp = waitpid(-1,NULL,0);
print tmp (which is the correct value of the child pid)
}

int main ()
{
  sigaction(SIGCHLD, my_signal_handler_for_sigchld)
  fork()
  if (child) //do something, return
  if parent // waitpid(child_pid, NULL,0); print value returned from this waitpid - it is -1
}

鸭preciate如果有人可以帮助我理解这一点。

Appreciate if someone helps me understand this.

推荐答案

您真的不需要办理 SIGCHLD 如果你的目的是运行一个子进程,做一些东西,然后等待它完成。在这种情况下,你只需要调用 waitpid函数当你准备进行同步。唯一 SIGCHLD 是有用的孩子终止异步通知,例如,如果你有一个互动(或长期运行的后台程序)应用程序的产卵各种儿童和需要要知道,当他们完成。然而, SIGCHLD 是非常糟糕/丑​​为此也一样,因为如果你使用的库code,创建子进程,你可能赶上了事件的图书馆儿童终止并用其处理他们的干扰。信号处理程序本质上是进程全局和处理全局状态,这通常是一件坏事(TM)。

You really don't need to handle SIGCHLD if your intent is to run a child process, do some stuff, then wait for it to finish. In that case, you just call waitpid when you're ready to synchronize. The only thing SIGCHLD is useful for is asynchronous notification of child termination, for example if you've got an interactive (or long-running daemon) application that's spawning various children and needs to know when they finish. However, SIGCHLD is really bad/ugly for this purpose too, since if you're using library code that creates child processes, you might catch the events for the library's children terminating and interfere with its handling of them. Signal handlers are inherently process-global and deal with global state, which is usually A Bad Thing(tm).

下面是当你有将终止异步子两个进程更好的方法:

Here are two better approaches for when you have child processes that will be terminating asynchronously:

方法1(选择 / 调查基于事件的):确保你从每个人都有一个管道/子进程创建。它可以是他们的标准输入/输出/标准错误,或只是一个额外的虚拟FD。当孩子进程终止,其管道年底将被关闭,你的主事件循环将检测在该文件描述符的活动。从事实,即它关闭,您应该意识到,子进程死了,和呼叫 waitpid函数收获僵尸。

Approach 1 (select/poll event-based): Make sure you have a pipe to/from each child process you create. It can be either their stdin/stdout/stderr or just an extra dummy fd. When the child process terminates, its end of the pipe will be closed, and your main event loop will detect the activity on that file descriptor. From the fact that it closed, you recognize that the child process died, and call waitpid to reap the zombie.

方法2(基于线程的):对于您创建的每个子进程,还创建一个线程,将立即拨打 waitpid函数的子进程的PID。当 waitpid函数成功返回,用你喜欢的线程同步原语,让程序的其余部分知道孩子终止,或者干脆打理一切,你需要在这个服务员做线程它终止之前。

Approach 2 (thread based): For each child process you create, also create a thread that will immediately call waitpid on the child process's pid. When waitpid returns successfully, use your favorite thread synchronization primitives to let the rest of the program know that the child terminated, or simply take care of everything you need to do in this waiter thread before it terminates.

这两种方法是模块化和图书馆友好(他们避免与可能被利用的子进程的code或库code的任何其他部分的干扰)。

Both of these approaches are modular and library-friendly (they avoid interfering with any other parts of your code or library code which might be making use of child processes).

这篇关于使用waitpid函数或sigaction的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆