2

在以下博文中:

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

有一个 'push' 方法定义如下:

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

我的问题是:

  1. 为什么在 scoped_lock 变量上调用了显式的“lock.unlock()”?

  2. 它的目的是什么?

  3. 是否可以安全地删除它,导致“notify_one”方法调用在 scoped_mutex 的范围内?

4

3 回答 3

6

The unlock is not necessary. It might reduce the time that the mutex is locked for slightly, however.

Keeping it or removing it will not affect thread safety or result in deadlocks.

EDIT: As the article mentions, however, leaving the unlock in there can result in less contention on the mutex. You might as well leave it in. Alternatively, use scope around the mutex, which I personally find highlights the scope of the mutex better if glancing at the code.

于 2012-05-22T08:05:14.913 回答
3

The explicit lock is so the that waiting thread isn't woken up by the notification only to have to block on the mutex. This is explained earlier in the article that you linked to.

The reason to still use a scoped_lock is to ensure that the mutex is properly unlocked in case the push fails and throws an exception.

于 2012-05-22T08:08:44.353 回答
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();
}
于 2012-05-22T08:09:39.223 回答