c++多线程编程中的虚假唤醒

以编写线程池为例,首先定义了任务队列(m_tasks),存放任务(function包装的函数指针),有多个worker线程执行worker函数,需要从任务队列取出任务,这时候就需要加锁判断任务队列是否有任务,假设任务队列添加一个任务我们使用notify_all唤醒阻塞的子线程时,这时候所有子线程都解除阻塞,如果一个子线程取走了任务,这时候任务队列如果没有任务的情况下,其他的子线程依然尝试从任务队列取任务,就是虚假唤醒(任务队列无任务,子线程仍然被唤醒去取任务)。

解决方法1:

把这一行:if(m_tasks.empty())中的if改为while。因为我们知道,跟if语句不同,while执行函数体后,会继续范围while的判断语句重新判断条件是否成立,所以如果任务队列的任务被一个子线程取走了,别的子线程重新判断m_tasks.empty是否成立,就可以避免虚假唤醒。

解决方法2:

wait函数第一个参数是unique_lock对象我们知道,其实它还可以接受一个谓词作为第二个参数,带有谓词的wait函数会在每次唤醒时检查条件(谓词),因此,我们可以:    m_condition.wait(locker,[&]{
        return !m_tasks.empty();
            });
当条件为真,继续占有锁,执行后续代码,否则释放锁,进入阻塞等待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值