我正在阅读一篇文章并阅读以下内容:假设我们要执行外部命令并等待它退出。我们不想永远等待,我们想要设置一些超时,之后我们将杀死子进程。这该怎么做?要运行命令,我们使用fork(2)和execve(2)。要等待特定进程退出,我们可以使用waitpid(2)函数,但它没有超时参数。我们还可以创建一个循环,在其中我们以超时作为参数调用sleep(3),并使用sleep(3)将被SIGCHLD信号中断的事实。这个解决方案几乎可以工作。它将包含竞争条件:如果进程立即退出,在我们调用sleep(3)之前,我们将等到超时到期。这是一场类似于前面描述的比赛。系统调用是如何中断的?孩子是将信号发送到父进程还是系统调用sleep(3)?我不知道系统调用如何停止执行并传递给父进程,系统调用是否像另一个进程一样?
答案 0 :(得分:1)
您可以使用gnu popen 参考gnu libc Pipe to a Subprocess来分叉孩子。
如果您想阻止孩子 重置 警告,这可能会有所帮助。
然后使用
警报和 setitimer 函数提供了一种进程在将来中断自身的机制。他们通过设置计时器来做到这一点;当计时器到期时,该过程接收信号。
注意您可以在执行
之前调用上面的可移植性注意: setitimer 和 getitimer 函数派生自BSD Unix,而警报函数由POSIX指定.1 标准。 setitimer 比警告更强大,但警报更广泛使用。
您还可以使用超时参考man timeout part of coreutils
一切顺利
答案 1 :(得分: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()
以上或超时后醒来之前,才会安排该过程。