linux - pause() 系统调用并接收 SIGINT 信号
问题描述
我是 Linux 和进程信号处理的初学者。假设我们有一个进程 A,它执行 pause() 函数,我们知道这会使当前进程进入睡眠状态,直到进程接收到信号。但是当我们键入 ctrl-c 时,内核也会向进程 A 发送一个 SIGINT,当 A 收到信号时,它会执行 SIGINT 的默认处理程序,该处理程序正在终止当前进程。所以我的问题是:
进程 A 先恢复还是处理程序先执行?
解决方案
为简单起见,我们假设进程 A 只有一个线程,它在调用中阻塞pause()
,并且只有一个信号被发送到进程。
进程 A 先恢复还是处理程序先执行?
信号处理程序首先执行,然后pause()
调用返回。
如果有多个信号怎么办?
INT
标准信号没有排队,因此如果您连续快速地向进程发送两个信号,则只会传递其中一个。如果有多个信号,则未指定顺序。
POSIX 实时信号呢?(
SIGRTMIN+0
到SIGRTMAX-0
)它们就像标准命名信号一样,除了它们是排队的(到一个限制),如果其中有多个待处理,它们会以递增的数字顺序传递。
如果同时有标准信号和实时信号挂起,则未指定哪些信号首先交付;尽管在实践中,在 Linux 和许多其他系统中,标准信号首先被传递,然后是实时信号。
如果进程中有多个线程怎么办?
内核将在没有屏蔽信号的线程中选择一个线程(通过
sigprocmask()
或pthread_sigmask()
),并使用该线程将信号传递给信号处理程序。如果一个调用中有多个线程阻塞
pause()
,其中一个会被唤醒。如果有多个未决信号,则未指定一个被唤醒的线程是否全部处理它们,或者是否唤醒了多个线程。
一般来说,我强烈建议阅读man 7 signal
、man 7 signal-safety
、man 2 sigaction
、man 2 sigqueue
和man 2 sigwaitinfo
手册页。(虽然链接指向 Linux 手册页项目,但每个页面都包含一个命名相关标准的符合部分,并且明确标记了特定于 Linux 的行为。)
推荐阅读
- django - 使用 Nginx+uwsgi+django 无法同时处理 websocket 和 xhr 请求
- forms - Symfony 4:handelrequest 没有收到任何提交的数据
- c# - ASP.NET MVC 4 API 的端点没有响应
- sql - 如何将单列转置为单行
- ansible - Ansible 任务在手动执行时失败:“跳过:没有匹配的主机”
- mysql - 按上月 SQL 查询
- angular - 将内容添加到动态创建的选项卡 - Angular 7
- pentaho - Pentaho 升级项目
- r - grplasso 作为 glm 模型
- javascript - 每页多个视口检查