2

As we know, std::unique_lock might release the mutex when it's destructor called.

Consider the behavior of the line 8th in the source below, lck.unlock(), my question is whether unlocking mutex before function return increase the concurrency or not?

MessageWrapper ServerLeftCommunicator::receive() {
  unique_lock<mutex> lck(recvMsgQCvMtx_);
  recvMsgQCv_.wait(lck, [this] {
    return ! recvMsgQ_.empty();
  });
  auto wrapper = recvMsgQ_.front();
  recvMsgQ_.pop();
  lck.unlock();
  return wrapper;
}

Thank you.

Qi W.
  • 706
  • 9
  • 21

2 Answers2

7

No. The first thing that will happen before you return is the destructor will call unlock. That is the only local variable that will be destructed, assuming return-value optimization is happening and that the type of wrapper is actually MessageWrapper.

Explicitly calling unlock in the hope that you will get some benefit would be considered bad style in this case.

Perhaps, if there's other non-trivial operations happening before the function returns, you might consider doing this. But it would be more appropriate to put the lock-specific stuff inside a scope block and not explicitly unlock. As with any concurrency optimisation, always reduce the scope of your lock to a minimum.

paddy
  • 60,864
  • 6
  • 61
  • 103
1

You don't really show enough code that we can estimate how expensive the various operations are.

However, it looks to me like your code can benefit from "named return value optimization", as the object wrapper is always returned. If it is being deduced as MessageWrapper, then what the compiler will do is construct wrapper directly in that target return value. This means that returning will not even have the cost of copying the returned value.

In that scenario, there is little to no benefit of unlocking early, since the return should cost much less than copying the object.

Chris Beck
  • 15,614
  • 4
  • 51
  • 87