首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++条件变量notify_one:释放锁之前还是之后?

C++条件变量notify_one:释放锁之前还是之后?
EN

Stack Overflow用户
提问于 2019-03-14 03:21:43
回答 1查看 4.4K关注 0票数 4

下面是有关C++条件变量的CPPConference.com代码示例

代码语言:javascript
复制
std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;

void worker_thread()
{
    // Wait until main() sends data
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, []{return ready;});

    // after the wait, we own the lock.
    std::cout << "Worker thread is processing data\n";
    data += " after processing";

    // Send data back to main()
    processed = true;
    std::cout << "Worker thread signals data processing completed\n";

    // Manual unlocking is done before notifying, to avoid waking up
    // the waiting thread only to block again (see notify_one for details)
    lk.unlock();
    cv.notify_one();
}

在通知另一个线程之前,我不太理解锁被释放的结尾部分。

  1. 如果代码将cv.notify_one()放在lk.unlock()之前,会起作用吗?
  2. 为什么将cv.notify_one()放在lk.unlock()之后是一个更好的实践?根据此页,“通知线程不需要持有与等待线程持有的锁相同的互斥锁;实际上,这样做是一种悲观,因为被通知的线程将立即再次阻塞,等待通知线程释放锁。”但是,在我看来,将notify_one放在解锁之前会导致通知->解锁->其他线程获得锁,而在解锁后放置notify_one的wile会导致解锁操作->notify_one>其他线程获得锁。这里有什么区别?
EN

回答 1

Stack Overflow用户

发布于 2019-03-14 03:38:25

  1. 链接是正确的,如果线程通知有锁,那么被通知的线程必须阻塞,直到通知线程释放锁为止。在多核处理器中,这是不必要的延迟。

你的比较是有缺陷的,因为它缺少细节。涉及两个线程,两个线程同时运行,您的比较忽略了这两个线程。

将notify_one放在解锁之前:

代码语言:javascript
复制
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:

代码语言:javascript
复制
notifying thread: notify 
notified thread: awaken -> attempt to acquire lock and succeed
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55154462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档