effolkronium
effolkronium

Reputation: 563

Why unique_lock call unlock, when he does not owning mutex?

In this example, std::unique_lock call with flag std::defer_lock. On cppreference written: "defer_lock_t do not acquire ownership of the mutex" and : "(destructor) unlocks the associated mutex, if owned "

And now, the question!

Why in this example, std::unique_lock calls unlock in destructors?

void transfer(Box &from, Box &to, int num)
{
    // don't actually take the locks yet
    std::unique_lock<std::mutex> lock1(from.m, std::defer_lock);
    std::unique_lock<std::mutex> lock2(to.m, std::defer_lock);

    // lock both unique_locks without deadlock
    std::lock(lock1, lock2);

    from.num_things -= num;
    to.num_things += num;

    // 'from.m' and 'to.m' mutexes unlocked in 'unique_lock' dtors
}

?????

Upvotes: 1

Views: 1376

Answers (1)

Xarn
Xarn

Reputation: 3560

Because std::defer_lock serves to say "I will obtain the lock somehow later on", which the call to std::lock(lock1, lock2) does. Because of this, the locks call unlock in destructor. To test this out, you could try giving the mutexes to std::lock directly: std::lock(from.m, to.m);. If you do this, the unique_locks will not unlock the mutexes, as they don't own them.

There is also std::adopt_lock, which says "I already own the lock".

These two approaches are mostly equivalent, except that you cannot use std::defer_lock with std::lock_guard, as it does not have lock method.

Upvotes: 4

Related Questions