notify和unlock的顺序

虚假唤醒

即使没有线程向条件变量发出信号,线程也可能从等待状态中唤醒。

注:虚假唤醒很容易被人误解为:如果有多个消费者,这些消费者可能阻塞在同一位置。当生产者通知not empty时,duque立即被第一个被唤醒的消费者清空,则后面的消费者相当于时被虚假唤醒了。

这种情况完全可以通过使用signal而非broadcast解决。signal只会唤醒某个线程,唤醒的依据为等待线程的优先级,若优先级相同,则依据线程的等待时长。

wait( std::unique_lock< std::mutex >& lock )

1.原子地解锁 lock ,阻塞当前执行线程
2.将它添加到于 *this 上等待的线程列表。线程将在执行 notify_all() 或 notify_one() 或者虚假唤醒时被解除阻塞
3.lock 再次锁定且 wait 退出

wait( std::unique_lock< std::mutex >& lock, Predicate pred )

等价于

while (!pred()) {

    wait(lock);
}

notify和unlock的顺序

notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。

将notify_one放在解锁之前:
notifying thread: notify -> eventually release lock
notified thread: awaken -> attempt to acquire lock and fail -> block until lock available -> acquire lock after notifying thread releases it

在解锁后放置notify_one:
notifying thread: notify
notified thread: awaken -> attempt to acquire lock and succeed

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值