【问题标题】:how can signals interrupt a system call信号如何中断系统调用
【发布时间】:2016-06-11 17:43:15
【问题描述】:

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

【问题讨论】:

    标签: linux signals ipc


    【解决方案1】:

    系统调用是如何中断的?子进程是向父进程发送信号还是系统调用 sleep(3)?

    当子进程执行系统调用exit(2)时,内核函数do_exit(),从那里exit_notify()和从那里do_notify_parent()被调用,将SIGCHLD发送到父母并致电__wake_up_parent()

    我不明白系统调用如何停止执行并传递给 父进程,系统调用和其他进程一样吗?

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

    【讨论】:

      【解决方案2】:

      你可以使用 gnu popen Ref gnu libc Pipe to a Subprocess fork 一个孩子。

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

      然后使用

      alarmsetitimer 函数为进程在将来中断自身提供了一种机制。他们通过设置计时器来做到这一点;当定时器到期时,进程收到一个信号。

      NB 你会调用上面的 before execve

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

      参考libc Setting Alarm

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

      一切顺利

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-10
        • 1970-01-01
        • 2012-11-01
        • 1970-01-01
        • 2013-04-11
        相关资源
        最近更新 更多