2016-06-11 135 views
1

我正在阅读文章并阅读以下内容:假设我们要执行外部命令并等待它退出。我们不想永远等待,我们想要设置一些超时后,我们将杀死子进程。这个怎么做?要运行一个命令,我们使用fork(2)和execve(2)。要等待特定的进程退出,我们可以使用waitpid(2)函数,但它没有超时参数。我们还可以创建一个循环,在该循环中我们将timeout作为参数调用sleep(3),并使用SIGCHLD信号中断sleep(3)的事实。这个解决方案几乎可以...工作。它将包含竞争条件:如果进程立即退出,在我们调用sleep(3)之前,我们将等待直到超时过期。这是一场类似于前面描述的比赛。系统调用如何中断?孩子将信号发送给父进程还是系统调用sleep(3)?我不知道系统调用如何停止执行并传递给父进程,是否像另一个进程一样调用系统调用?信号如何中断系统调用

回答

1

如何在系统调用中断?孩子将信号发送给父进程还是系统调用sleep(3)?

当子进程执行系统调用出口(2),内核函数do_exit(),从那里exit_notify(),并从那里do_notify_parent()被调用,它发送SIGCHLD父和调用__wake_up_parent()

我不知道系统调用如何停止执行并传递给 父进程,系统调用是否像另一个进程?

系统调用底层sleep()将调用进程置于TASK_INTERRUPTIBLE状态 - 参见e。 G。 Sleeping in the Kernel。之后,这个过程根本就不会被调度,直到通过上面的__wake_up_parent()或超时唤醒。

1

你可以用gnu掏孩子popen参考gnu libc Pipe to a Subprocess

,如果你想从能够停止孩子这可能有助于重新报警

然后用

报警setitimer功能的过程中断自己在未来的机制。他们通过设置一个计时器来实现这一点当定时器到期时,进程接收到一个信号。

NB你会调用上面以前 execve的

可移植性注:setitimergetitimer功能从BSD Unix的衍生,而被指定的报警功能POSIX.1标准。 setitimer报警功能更强大,但是报警更为广泛使用

参考libc Setting Alarm

你也可以使用超时参考man timeout part of coreutils

所有最优秀的