事件通知怎样变成动作
Linux信号可以由内核事件或发送接口产生,目标可以是进程,也可以是特定线程。每种信号有处理方式,可采用默认动作、忽略或安装处理函数;默认动作包括终止、暂停、继续和其他规定行为。
处理方式是进程范围属性,同一进程各线程共享;屏蔽集合却是线程属性。面向整个进程的信号可递送给一个没有屏蔽它的合适线程,不意味着同一通知必然让所有线程各运行一次处理函数。
参考:[1]
屏蔽不等于忽略,普通信号不累计计数
屏蔽信号通常推迟递送,使它在解除屏蔽前处于等待状态,这与直接选择忽略不同。SIGKILL和SIGSTOP不能捕获、屏蔽或忽略,因此程序不能为所有信号统一安装自定义处理逻辑。
普通信号同一类型多次产生而仍在等待时,不会逐个累计为消息队列;解除屏蔽后可能只处理一次。实时信号则支持多个实例排队及相应顺序规则,但队列资源仍有限,也不等于保证某个硬实时处理期限。
参考:[1]
处理函数运行在被打断的上下文中
递送可使线程暂时转入用户定义处理函数,返回后再恢复原执行状态。这不是自动新建一个独立线程;处理函数可能打断正在修改库内部数据的代码,因而不能按普通业务回调那样随意调用所有函数。
异步信号安全规则限制可从处理函数调用的接口。Linux文档以printf等缓冲I/O说明重入风险:若共享内部状态只更新了一半,再次进入便可能出错。需要复杂处理时,可采用同步等待信号等设计,而不是把任意工作塞进异步处理函数。