在消费者循环中重用unique_lock

时间:2017-07-31 12:24:00

标签: c++ multithreading c++11 condition-variable

我在第119页的Bjarne Stroustrup的“The C ++ Programming Language,4th Edition”中偶然发现了以下代码:

queue<Message> mqueue;
condition_variable mcond;
mutex mmutex;

void consumer()
{
    while(true) {
        unique_lock<mutex> lck{mmutex};
        mcond.wait(lck);

        auto m = mqueue.front();
        mqueue.pop();
        lck.unlock();
        // process m
    }
}

还有一个生产者线程将Message推送到队列并在循环中通知等待的线程。

我的问题是:是否需要在循环的每次迭代中创建一个新的unique_lock?对我来说这似乎是不必要的,因为在下一行mcond.wait(lck)中,锁在锁定之后直接解锁。

从性能的角度来看,lck变量不能在循环开始之前初始化吗?

1 个答案:

答案 0 :(得分:8)

如上所述on cppreferencetf checkout /recursive *.cs 构造函数是这样的:

std::unique_lock

构造函数将执行以下操作:

  

构造一个unique_lock,其中m作为关联的互斥锁。 另外通过调用m.lock()来锁定关联的互斥锁。如果当前线程已经拥有互斥锁,除非互斥锁是递归的,否则行为是未定义的。

因此代码会在每次迭代时锁定互斥锁。将它移出循环会改变逻辑。