1

A thread has the following control flow:

mutex.lock()
if (condition) {
    // do synced things
    mutex.unlock();
    // do parallel things
} else {
    // do other synced things
    mutex.unlock();
    // do other parallel things
}

Note how the four do parts all execute different things.

How do I replace direct calls to lock and unlock into using std::lock_guard instead?

Anonymous Entity
  • 3,254
  • 3
  • 27
  • 41

2 Answers2

7

std::unique_lock looks like what you're looking for. Semantics are similar to std::lock_guard, but allows more sophisticated constructs. So in your case you still get the exception safety, but also can explicitly unlock early. Something like:

std::unique_lock<decltype(mutex)> guard(mutex); // calls mutex.lock() like lock_guard
if (condition) {
    // do synced things
    guard.unlock();
    // do parallel things
} else {
    // do other synced things
    guard.unlock();
    // do other parallel things
}
// unlocks on leaving scope, if held similar to lock_guard
Community
  • 1
  • 1
Flexo
  • 87,323
  • 22
  • 191
  • 272
1
bool cond;
{
    std::lock_guard<std::mutex> lg(mutex);
    cond = global_condition;
    if (cond){
        // do some synced stuff
    } else {
        // do the other synced stuff
    }
}

if (cond){
    // do parallel stuff
} else {
    // do the other parallel stuff
}

since the parallel stuff in both the cases is done after unlocking mutex guarding the global condition, it means that the condition either cannot change, or we don't care if it changes. Thus we can save the value and if-else again later based on the saved value.

Xarn
  • 3,460
  • 1
  • 21
  • 43