线程间事件通知

本文介绍了线程间事件通知的三种方式:管道、条件变量和eventfd。针对条件变量在事件通知中的问题,文章详细讨论了可能导致的竞争条件和死锁风险,并提出了解决方案。eventfd被推荐为更适合事件通知的方法,因为它具有计数器特性和多路复用支持,避免了资源泄漏和同步问题。

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

事件通知

有的时候我们需要事件通知的场景,比如A线程注册了一个异步的回调,开始处理某些流程,这个时候该处理完毕的都处理完毕了,开始等待回调的结果。B线程进行I/O,I/O完毕进行回调然后填充A线程注册回调时传递的参数。这个时候B线程工作完毕是需要通知A线程,它已经干完毕了A线程可以继续下面的步骤了。
那么这个时候就可以进行事件通知了。

事件通知方式

下面三种方式都可以进行事件通知

  1. pipe
  2. pthread_mutex_cond
  3. eventfd
管道事件通知

管道是一个半双工的进程间通信的一种方式,我们可以参用B线程完毕后写入管道,A线程去阻塞读取即可完成事件通知。但是这样的开销就是内核得给进程开辟一个缓冲区比较浪费内存。

条件变量

条件变量多用于生产者/消费者中发现条件不允许所做的一些同步,但是用于事件通知的时候就很难。如下这个时候会产生很多竞争条件。
比如方式1中A线程可能在注册回调到进行Wait的那段时间段内,B线程已经signal过了,这个时候A线程就可能一直阻塞在Wait函数。
方式2 可以在 CallBack结构中加一个标志用于同步,但是这个时候线程B可能会访问非法内存崩溃,因为可能在它判断wake的时候,这个时候线程A已经完成操作 析构了 CallBack,这个时候线程B访问就是非法内存直接崩溃。
方式3 把delete CallBack 放到线程B 即可,唤醒A线程后,通过加锁访问CallBack并析构它完成资源释放。这个时候看起来是正确的,终于实现了事件通知。但是还是有个问题,如果这把锁是全局锁就可能发生死锁,可以想象一下如果是把全局锁,A线程执行完毕了第一个请求,开始执行第二个请求它获得了锁并进行了wait,线程B处于第一个请求将要获得锁进行delete数据,这个时候就发生死锁了互相等待。

方式1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值