linux 异步创建进程,c-如何在Linux上执行异步信号处理程序?

源1(Andries Brouwer)对于单线程进程是正确的。 Source#2(SCO Unix)对于Linux是错误的,因为Linux不喜欢sigwait(2)中的线程。 Moshe Bar关于第一个可用线程是正确的。

哪个线程获取信号? Linux的手册页是很好的参考。 进程使用带有CLONE_THREAD的clone(2)创建多个线程。 这些线程属于“线程组”,并且共享单个进程ID。 clone(2)的手册说,

信号可以整体发送到线程组(即   TGID)使用kill(2),或使用特定线程(即TID)使用   tgkill(2)。

信号的处置和动作是全过程的:如果   未处理的信号传递到线程,则将影响   (终止,停止,继续,被忽略)的所有成员   线程组。

每个线程都有自己的信号掩码,如sigprocmask(2)所设置,   但信号可以挂起:在整个过程中   (即,可交付给线程组的任何成员),当   发送带有kill(2); 或对于单个线程,与   tgkill(2)。 调用sigpending(2)返回一个信号集   是整个过程中待处理信号的结合,并且   等待调用线程的信号。

如果使用kill(2)将信号发送到线程组,则   线程组已为信号安装了处理程序,然后   处理程序将在任意选择的一个中调用   尚未阻止该信号的线程组的成员。   如果组中的多个线程正在等待接受相同的线程   sigwaitinfo(2)发出信号,内核将任意   选择这些线程之一以接收使用发送的信号   杀死(2)。

Linux不是SCO Unix,因为Linux可能会将信号提供给任何线程,即使某些线程正在等待信号(使用sigwaitinfo,sigtimedwait或sigwait),而有些线程则没有。 sigwaitinfo(2)的手册警告说,

在正常使用情况下,调用程序会通过   事先调用sigprocmask(2)(这样,默认设置为   如果这些信号在   连续调用sigwaitinfo()或sigtimedwait()且不   为这些信号建立处理程序。 在多线程程序中   信号应在所有线程中被阻止,以防止   根据其在线程中的默认配置处理信号   除了调用sigwaitinfo()或sigtimedwait()的那个。

为信号选择线程的代码位于linux / kernel / signal.c中(链接指向GitHub的镜像)。 请参见功能旺旺信号()和completes_signal()。 该代码为信号选择第一个可用线程。 可用线程是不会阻塞信号且队列中没有其他信号的线程。 该代码碰巧先检查主线程,然后以我不知道的顺序检查其他线程。 如果没有线程可用,则信号将被阻塞,直到某个线程取消阻塞信号或清空其队列为止。

线程收到信号后会发生什么? 如果有信号处理程序,则内核使线程调用该处理程序。 大多数处理程序在线程的堆栈上运行。 如果进程使用sigaltstack(2)提供堆栈,并且sigaction(2)使用SA_ONSTACK设置处理程序,则处理程序可以在备用堆栈上运行。 内核将一些东西压入所选堆栈,并设置一些线程的寄存器。

要运行处理程序,线程必须在用户空间中运行。 如果线程在内核中运行(可能是系统调用或页面错误),则它只有在进入用户空间后才运行处理程序。 内核可以中断某些系统调用,因此线程现在可以运行处理程序,而无需等待系统调用完成。

信号处理程序是C函数,因此内核遵循体系结构调用C函数的约定。 每种架构(例如arm,i386,powerpc或sparc)都有自己的约定。 对于powerpc,要调用handler(signum),内核会将寄存器r3设置为signum。 内核还将处理程序的返回地址设置为信号蹦床。 返回地址按照约定放在堆栈上或寄存器中。

内核在每个过程中放置一个信号蹦床。 该蹦床调用sigreturn(2)还原线程。 在内核中,sigreturn(2)从堆栈中读取一些信息(例如保存的寄存器)。 内核在调用处理程序之前已将该信息压入堆栈。 如果存在中断的系统调用,则内核可能重新启动该调用(仅在处理程序使用SA_RESTART的情况下),或者使用EINTR使调用失败,或者返回简短的读写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值