在scoped_lock上解锁的无关紧要

时间:2012-05-22 07:58:13

标签: c++ multithreading thread-safety mutex condition-variable

在以下博文中:

http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

有一个推动'方法定义如下:

void push(Data const& data)
{
   boost::mutex::scoped_lock lock(the_mutex);
   the_queue.push(data);
   lock.unlock();
   the_condition_variable.notify_one();
}

我的问题是:

  1. 为什么会有一个明确的' lock.unlock()'被scoped_lock变量调用?

  2. 它的目的是什么?

  3. 是否可以安全删除,从而导致' notify_one'方法调用是否在scoped_mutex的范围内?

3 个答案:

答案 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();
}