信号如何中断系统调用

时间:2016-06-11 17:43:15

标签: linux signals ipc

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

2 个答案:

答案 0 :(得分:1)

您可以使用gnu popen 参考gnu libc Pipe to a Subprocess来分叉孩子。

如果您想阻止孩子 重置 警告,这可能会有所帮助。

然后使用

  

警报 setitimer 函数提供了一种进程在将来中断自身的机制。他们通过设置计时器来做到这一点;当计时器到期时,该过程接收信号。

注意您可以在执行

之前调用上面的
  

可移植性注意: setitimer getitimer 函数派生自BSD Unix,而警报函数由POSIX指定.1 标准。 setitimer 警告更强大,但警报更广泛使用

参考libc Setting Alarm

您还可以使用超时参考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()以上或超时后醒来之前,才会安排该过程。