首页 > 解决方案 > pause() 系统调用并接收 SIGINT 信号

问题描述

我是 Linux 和进程信号处理的初学者。假设我们有一个进程 A,它执行 pause() 函数,我们知道这会使当前进程进入睡眠状态,直到进程接收到信号。但是当我们键入 ctrl-c 时,内核也会向进程 A 发送一个 SIGINT,当 A 收到信号时,它会执行 SIGINT 的默认处理程序,该处理程序正在终止当前进程。所以我的问题是:

进程 A 先恢复还是处理程序先执行?

标签: linuxprocessexception-handlingsignals

解决方案


为简单起见,我们假设进程 A 只有一个线程,它在调用中阻塞pause(),并且只有一个信号被发送到进程。

进程 A 先恢复还是处理程序先执行?

信号处理程序首先执行,然后pause()调用返回。


  • 如果有多个信号怎么办?

    INT标准信号没有排队,因此如果您连续快速地向进程发送两个信号,则只会传递其中一个。

    如果有多个信号,则未指定顺序。
     

  • POSIX 实时信号呢?(SIGRTMIN+0SIGRTMAX-0

    它们就像标准命名信号一样,除了它们是排队的(到一个限制),如果其中有多个待处理,它们会以递增的数字顺序传递。

    如果同时有标准信号和实时信号挂起,则未指定哪些信号首先交付;尽管在实践中,在 Linux 和许多其他系统中,标准信号首先被传递,然后是实时信号。
     

  • 如果进程中有多个线程怎么办?

    内核将在没有屏蔽信号的线程中选择一个线程(通过sigprocmask()pthread_sigmask()),并使用该线程将信号传递给信号处理程序。

    如果一个调用中有多个线程阻塞pause(),其中一个会被唤醒。如果有多个未决信号,则未指定一个被唤醒的线程是否全部处理它们,或者是否唤醒了多个线程。

一般来说,我强烈建议阅读man 7 signalman 7 signal-safetyman 2 sigactionman 2 sigqueueman 2 sigwaitinfo手册页。(虽然链接指向 Linux 手册页项目,但每个页面都包含一个命名相关标准的符合部分,并且明确标记了特定于 Linux 的行为。)


推荐阅读