I have some function which trying to lock std::mutex
and if mutex successfully locked, function creates std::thread
with lambda-function as thread function parameter, and also passes it lock using std::move()
:
static std::mutex mtx;
// some mutex defended stuff
void someFunc() {
// try lock mutex using unique_lock
std::unique_lock<std::mutex> lock(mtx, std::try_to_lock);
if(!lock.owns_lock()) {
return; // locking fails
}
// task for thread
auto task = [&](std::unique_lock<std::mutex>&& lock) {
// do async work and release lock when it done
lock.unlock();
// do something after releasing lock
};
// create thread, pass lock
std::thread taskThread(task, std::move(lock));
taskThread.detach();
}
I've got compiler error:
<lambda_1918cc58d906c210588b1a8bb33f1b0d>::operator
()(std::unique_lock<_Mutex> &&) const' : cannot convert parameter 1 from
'std::unique_lock<_Mutex>' to 'std::unique_lock<_Mutex> &&'
How should I proper pass std::unique_lock
to my lambda?
UPD: In fact this function is a native C API libaray call, it tryes to start some library operation async and returns control immediately in any case, returning some return code to caller. This code is simplified to concentrate on particaular issue.
Your code compiles on both gcc and clang. It fails to compile on VS2013 (VC12) because of a bug in the implementation that requires the arguments to the std::thread
constructor to be copyable. This results in the compiler attempting to copy the std::unique_lock
, which, of course, fails.
However, your code has undefined behavior because you're locking and unlocking the mutex
in two different threads, which is not allowed. The thread unlocking it must be the same as the one that had previously locked it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With