notify和unlock的顺序

虚假唤醒

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

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

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

wait( std::unique_lockstd::mutex& lock )

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

wait( std::unique_lockstd::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

发布了190 篇原创文章 · 获赞 70 · 访问量 13万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览