Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handing over locked std::unique_lock to new threads

Consider the following example where I create a std::mutex, lock it and then hand the lock over to another thread :

#include <future>
#include <mutex>

int main()
{
    // Create and lock a mutex
    std::mutex mutex;
    std::unique_lock<decltype(mutex)> lock(mutex);

    // Hand off the lock to another thread
    auto promise = std::async(std::launch::async, 
        [lock{ std::move(lock) }]() mutable
        {
            // Unlock the mutex
            lock.unlock();
        });

    promise.get();

    return 0;
}

The example seems to run fine with gcc 6.3 but fails an run-time assert with Visual Studio 2015 with the error "unlock of unowned mutex".

I've noticed that if I switch the example to use std::shared_timed_mutex and std::shared_lock then the example completes successfully. I've also noticed that if I remove the explicit unlock then the example completes successfully, but the mutex doesn't seem to unlock at all (crashes with VC if I try to lock the mutex again, gcc doesn't complain).

Based on what I read on cppreference.com about std::unique_lock it seems to me like the original example should run fine. Does something about std::mutex or std::unique_lock forbid a thread to unlock if another thread did the lock? Is this perhaps a VC bug?

like image 901
François Andrieux Avatar asked Feb 04 '23 09:02

François Andrieux


1 Answers

According to http://en.cppreference.com/w/cpp/thread/mutex/unlock :

The mutex must be locked by the current thread of execution, otherwise, the behavior is undefined.

The documentation for std::shared_timed_mutex::unlock() has the same specification, so it's not guaranteed to work with that class either.

like image 143
Daniel Schepler Avatar answered Feb 16 '23 03:02

Daniel Schepler