事件通知
有的时候我们需要事件通知的场景,比如A线程注册了一个异步的回调,开始处理某些流程,这个时候该处理完毕的都处理完毕了,开始等待回调的结果。B线程进行I/O,I/O完毕进行回调然后填充A线程注册回调时传递的参数。这个时候B线程工作完毕是需要通知A线程,它已经干完毕了A线程可以继续下面的步骤了。
那么这个时候就可以进行事件通知了。
事件通知方式
下面三种方式都可以进行事件通知
- pipe
- pthread_mutex_cond
- eventfd
管道事件通知
管道是一个半双工的进程间通信的一种方式,我们可以参用B线程完毕后写入管道,A线程去阻塞读取即可完成事件通知。但是这样的开销就是内核得给进程开辟一个缓冲区比较浪费内存。
条件变量
条件变量多用于生产者/消费者中发现条件不允许所做的一些同步,但是用于事件通知的时候就很难。如下这个时候会产生很多竞争条件。
比如方式1中A线程可能在注册回调到进行Wait的那段时间段内,B线程已经signal过了,这个时候A线程就可能一直阻塞在Wait函数。
方式2 可以在 CallBack结构中加一个标志用于同步,但是这个时候线程B可能会访问非法内存崩溃,因为可能在它判断wake的时候,这个时候线程A已经完成操作 析构了 CallBack,这个时候线程B访问就是非法内存直接崩溃。
方式3 把delete CallBack 放到线程B 即可,唤醒A线程后,通过加锁访问CallBack并析构它完成资源释放。这个时候看起来是正确的,终于实现了事件通知。但是还是有个问题,如果这把锁是全局锁就可能发生死锁,