在以下博文中:
有一个推动'方法定义如下:
void push(Data const& data)
{
boost::mutex::scoped_lock lock(the_mutex);
the_queue.push(data);
lock.unlock();
the_condition_variable.notify_one();
}
我的问题是:
为什么会有一个明确的' lock.unlock()'被scoped_lock变量调用?
它的目的是什么?
是否可以安全删除,从而导致' notify_one'方法调用是否在scoped_mutex的范围内?
答案 0 :(得分:6)
无需解锁。但是,它可能会减少互斥锁被锁定的时间。
保留或删除它不会影响线程安全或导致死锁。
编辑:正如文章所提到的那样,将解锁保留在那里可以减少对互斥锁的争用。您也可以将其保留。或者,在互斥锁周围使用范围,我个人发现,如果查看代码,我会更好地突出显示互斥锁的范围。
答案 1 :(得分:3)
显式锁是这样的,等待线程不会被通知唤醒,只能在互斥锁上阻塞。这在前面链接到的文章中有解释。
仍然使用scoped_lock
的原因是为了确保在推送失败的情况下正确解锁互斥锁并抛出异常。
答案 2 :(得分:3)
第1点和第2点可以通过以下原则回答:您应该尽可能少地握住锁。一旦数据被推入队列,您就不再需要将其锁定。
您可以按照建议移除解锁,但需要将锁定保持更长时间。
或者,可以通过添加新范围来删除解锁本身,如下所示:
void push(Data const& data)
{
{ // new scope
boost::mutex::scoped_lock lock(the_mutex);
the_queue.push(data);
} // scope ends, lock gets destroyed
the_condition_variable.notify_one();
}