如何编写信号安全的应用程序?
场景一:不需要处理信号
场景二:需要处理信号
同步方案
异步方案
信号处理逻辑与程序逻辑位于同一个上下文
方案设计一
由于给每个信号唯一的标记位置,因此,所有信号转变为不可靠信号;并且仅保留最近递达的信号信息
方案设计二
将任务分解为子任务 (每个任务可对应一个函数)
#include <sys/select.h>
#include <sys/signalfd.h>
int signalfd(int fd, const sigset_t* mask, int flag);
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout);
先屏蔽所有信号 (无法递达进程),之后为屏蔽信号创建文件描述符;当时机成熟,通过 read() 系统调用读取未决信号 (主动接收信号)
由于使用了 select 机制,即便没有信号需要处理,也需要等待 select 超时,任务实时性受到影响
使用独立任务处理信号,程序逻辑在其他任务中执行
即:通过多线程分离信号处理与程序逻辑
信号的发送目标是进程,而不是某个特定的线程
发送给进程的信号仅递送给一个进程
内核从不会阻塞目标信号的线程中随机选择
每个线程拥有独立的信号屏蔽掩码
主线程:对目标信号设置信号处理的方式
其他线程:首先屏蔽所有可能的信号,之后执行任务代码
进程:应用程序的一次加载执行 (系统执行资源分配的基本单位)
线程:进程中的程序执行流
头文件:#include<pthread.h>
线程创建函数:int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine)(void*), void* arg);
线程标识:
线程等待:
多数模式不需要处理信号,因此可直接屏蔽信号
需要处理信号的程序,重点考虑信号安全性问题