信号如何中断系统调用

how can signals interrupt a system call

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

你可以使用 gnu popen Ref gnu libc Pipe to a Subprocess fork a child。

如果您想阻止 child 能够 reset alarm[=35],这可能会有所帮助=].

然后使用

The alarm and setitimer functions provide a mechanism for a process to interrupt itself in the future. They do this by setting a timer; when the timer expires, the process receives a signal.

注意你会调用上面的before execve

Portability Note: The setitimer and getitimer functions are derived from BSD Unix, while the alarm function is specified by the POSIX.1 standard. setitimer is more powerful than alarm, but alarm is more widely used.

参考 libc Setting Alarm

您也可以使用 timeout Ref man timeout part of coreutils

祝一切顺利

How is the system call interrupted? does the child send the signal to the parent process or the the system call sleep(3)?

子进程执行系统调用exit(2)时,调用内核函数do_exit(), from there exit_notify() and from there do_notify_parent(),向父进程发送SIGCHLD,调用 __wake_up_parent().

I don't get how the system call stop execution and passes to the parent process, is the system call like another process?

底层系统调用 sleep() 将调用进程置于状态 TASK_INTERRUPTIBLE - 参见 e。 G。 Sleeping in the Kernel。在那之后,这个过程只是没有被安排,直到被上面的 __wake_up_parent() 或超时唤醒。