linux 信号
sigset_t 信号集类型
sigfillset(...) 初始化所有信号位,值为 1。
sigemptyset(...) 清空所有信号,值为0.
sigaddset(...) 向信号集中添加信号.
pthread_sigmask(...)设置线程掩码(即:被屏蔽的信号集)。
sighold(...) 把指定信号添加到掩码中
sigrelse(...)从掩码中移除指定信号
sigignore(...)忽略指定信号
sigaction(signum, &act, &oldact) posix api设置信号处理函数。
ceph osd服务中的信号处理
初始化处理信号的handler
init_async_signal_handler();
SignalHandler是一个线程对象,专门用来处理信号。
g_signal_handler = new SignalHandler;
int r = pipe(pipefd); 创建一个管道主要用于管理该线程的生命周期
create();创建线程
block_signals(to_block, &old_sigset); 屏蔽SIGPIPE 信号,
*entry()线程入口。
struct pollfd fds[33];
int r = poll(fds, num_fds, -1);
通过IO复用技术poll实现统一时间源,所有通过g_signal_handler注册的信号的处理最终都会间接性的转到这里。
ceph中的专业信号处理线程:
SignalHandler是ceph中用于处理信号的线程对象。
signalHandler的核心成员:
int pipefd[2]; 用来构建管道,实现不同线程间的通信,主要用于通知信号处理线程更新监听的信号集。
safe_handler *handlers[32]; 所有信号处理线程维护的信号和对应的处理方法都会维护在该实例中。
sate_handler是SignalHandler的内部类型
struct safe_handler {
int pipefd[2]; // write to [1], read from [0] //接收到信号的线程把信号事件转交个信号处理线程使用的管道
signal_handler_t handler; //对应信号处理函数
};
为信号注册处理函数
register_handler(int signum, signal_handler_t handler, bool oneshot);
撤销信号的处理函数
unregister_handler(int signum, signal_handler_t handler);
用于触发信号处理线程更新维护的信号列表
void signal_thread()
提供给其他线程来通知信号处理线程接收到的信号
queue_signal(int signum)
总之,其他线程会对需要处理的信号设置一个hook,来通知信号处理线程。其本身只把信号事件通知给信号处理线程,不做其他处理。这里写代码片