libevent对信号的处理_一个博客id_新浪博客

我们知道,在操作系统中,我们无法预测信号事件会怎么发生,所以几乎很难实现对信号事件的监听。


Libevent对于信号的处理是采用统一事件源的方式。简单地说,就是把信号也转换成IO事件,集成到Libevent中。


统一事件源的工作原理如下:假如用户要监听SIGINT信号,那么在实现的内部就对SIGINT这个信号设置捕抓函数。此外,在实现的内部还要建立一条管道(pipe),并把这个管道加入到多路IO复用函数中。当SIGINT这个信号发生后,捕抓函数将会被调用。而这个捕抓函数的工作就是往管道写入一个字符(这个字符往往等于所捕抓到信号的信号值)。此时,这个管道就变成是可读的了,多路IO复用函数能检测到这个管道变成可读的了。换言之,多路IO复用函数检测到SIGINT信号的发生,也就完成了对信号的监听工作。这个过程如下图所示:
libevent对信号的处理_一个博客id_新浪博客_第1张图片

IO函数返回就绪的信号事件,libevent会帮助调用对应相应的信号处理函数(回调函数)。


evsig_add函数还调用了_evsig_set_handler函数完成设置Libevent内部的信号捕抓函数。


了解完统一事件源的工作原理,现在来看一下Libevent具体的实现细节。按照上述的介绍,内部实现的工作有:
  1. 创建一个管道(Libevent实际上使用的是socketpair)
  2. 为这个socketpair的一个读端创建一个event,并将之加入到多路IO复用函数的监听之中
  3. 设置信号捕抓函数
  4. 有信号发生,就往socketpair写入一个字节

        统一事件源能够工作的一个原因是:多路IO复用函数都是可中断的。即处理完信号后,会从多路IO复用函数中退出,并将errno赋值为EINTR。有些OS的某些系统调用,比如Linux的read,即使被信号终端了,还是会自启动的。即不会从read函数中退出来。

信号捕捉函数是怎么实现的?


转载自:https://blog.csdn.net/luotuo44/article/details/38538991

你可能感兴趣的:(java,python,linux,嵌入式,面试)