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

本文详细介绍了Libevent如何通过统一事件源方式处理信号事件。它将信号转换为IO事件,利用管道机制和信号捕获函数实现信号监听。文章还探讨了多路IO复用函数的中断机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


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


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

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.youkuaiyun.com/luotuo44/article/details/38538991

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值