I am trying to pass a std::unique_lock()
to a std::thread
as shown in the below code snippet and the application crashes with "Unlock of unowned mutex" exception when I try to unlock()
the lock in the thread in MSVS
std::mutex g_mutex; // Available globally
//SomeClass.cpp`
SomeClass::func1()
{
std::unique_lock<std::mutex> lock(g_mutex);
//Do stuff
AnotherClass->func2(lock);`
}
//AnotherClass.cpp
AnotherClass::func2(std::unique_lock<std::mutex>& lock)
{
//Do stuff
//lock.unlock() works OK here
thread = std::make_unique<std::thread>(std::bind(&AnotherClass:threadFun, this, std::ref(lock)));
return;
}
AnotherClass::threadFunc(std::unique_lock<std::mutex>& lock)
{
// Do stuff
lock.unlock(); // Aborts the application with **"Unlock of unowned mutex"** here`
}
What's the issue here?
I tried passing passing the lock to the thread using std::move()
and that didn't work either. I would like to know what mistake I am doing in the above code and is there better alternative to what I am doing?
The lock in func1
goes out of scope when the function returns. At that point, lock
s destructor is called and it will then call unlock()
on the mutex.
lock.unlock();
in threadFunc
also unlocks the mutex and you therefore have a double unlock, with undefined behavior as a result.
Also, you must only unlock the mutex from the thread which locked it:
The mutex must be locked by the current thread of execution, otherwise, the behavior is undefined.