在消费者循环中重用 unique_lock
Reusing a unique_lock in a consumer loop
我在 Bjarne Stroustrup 的 "The C++ Programming Language, 4th Edition" 第 119 页上无意中发现了以下代码:
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
变量不能在循环开始之前初始化吗?
如 on cppreference 所述,std::unique_lock
构造函数是这样的:
explicit unique_lock( mutex_type& m );
构造函数将执行以下操作:
Constructs a unique_lock with m as the associated mutex. Additionally locks the associated mutex by calling m.lock(). The behavior is undefined if the current thread already owns the mutex except when the mutex is recursive.
所以代码在每次迭代时都锁定了互斥体。将其移出循环会改变逻辑。
我在 Bjarne Stroustrup 的 "The C++ Programming Language, 4th Edition" 第 119 页上无意中发现了以下代码:
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
变量不能在循环开始之前初始化吗?
如 on cppreference 所述,std::unique_lock
构造函数是这样的:
explicit unique_lock( mutex_type& m );
构造函数将执行以下操作:
Constructs a unique_lock with m as the associated mutex. Additionally locks the associated mutex by calling m.lock(). The behavior is undefined if the current thread already owns the mutex except when the mutex is recursive.
所以代码在每次迭代时都锁定了互斥体。将其移出循环会改变逻辑。