移动unique_lock< recursive_mutex>到另一个线程 [英] Moving a unique_lock<recursive_mutex> to another thread
问题描述
我想知道当你移动包含 recursive_mutex
的 unique_lock
时会发生什么。
I was wondering what happens when you move a unique_lock
that holds a recursive_mutex
.
具体来说,我正在查看这段代码:
Specifically, I was looking at this code:
recursive_mutex g_mutex;
#define TRACE(msg) trace(__FUNCTION__, msg)
void trace(const char* function, const char* message)
{
cout << std::this_thread::get_id() << "\t" << function << "\t" << message << endl;
}
future<void> foo()
{
unique_lock<recursive_mutex> lock(g_mutex);
TRACE("Owns lock");
auto f = std::async(launch::async, [lock = move(lock)]{
TRACE("Entry");
TRACE(lock.owns_lock()? "Owns lock!" : "Doesn't own lock!"); // Prints Owns lock!
this_thread::sleep_for(chrono::seconds(3));
});
TRACE(lock.owns_lock()? "Owns lock!" : "Doesn't own lock!"); // Prints Doesn't own lock!
return f;
}
int main()
{
unique_lock<recursive_mutex> lock(g_mutex);
TRACE("Owns lock");
auto f = foo();
TRACE(lock.owns_lock()? "Owns lock!" : "Doesn't own lock!"); // Prints Owns lock!
f.wait();
TRACE(lock.owns_lock()? "Owns lock!" : "Doesn't own lock!"); // Prints Owns lock!
}
这个示例代码的输出使我感到惊讶。 main()中的 unique_lock
如何知道线程释放了互斥?
The output of this sample code surprised me a lot. How does the unique_lock
in main() know that the thread released the mutex? Is it real?
推荐答案
您似乎将一些魔法属性归为 unique_lock
。它没有任何,它是一个非常简单的类。它有两个数据成员, Mutex * pm
和 bool拥有
(仅为显示成员名称)。 lock()
只是 pm-> lock(); owns = true;
和 unlock
会执行 pm-> unlock owns = false;
。析构函数是 if(owns)unlock();
。将构造函数副本移动到这两个成员上,并相应地将原始对象设置为 nullptr
和 false
。 owns_lock()
返回 owns
成员的值。
You appear to ascribe some magic properties to unique_lock
. It doesn't have any, it's a very simple class. It has two data members, Mutex* pm
and bool owns
(member names shown for exposition only). lock()
is simply pm->lock(); owns = true;
, and unlock
does pm->unlock(); owns = false;
. The destructor is if (owns) unlock();
. Move constructor copies over the two members, and sets them in the original to nullptr
and false
, correspondingly. owns_lock()
returns the value of owns
member.
所有的线程同步魔术都在互斥体本身,它的 lock()
和 unlock()
方法。 unique_lock
只是一个简单的包装。
All the thread-synchronizing magic is in the mutex itself, and its lock()
and unlock()
methods. unique_lock
is merely a thin wrapper around it.
现在,调用 .unlock()
必须作为先决条件,保持mutex(意味着该线程以前在其上调用 lock()
),否则程序显示未定义的行为。这是真的,无论你是否显式调用 unlock
,或者骗一些帮助,如 unique_lock
调用它。
Now, the thread that calls mutex.unlock()
must, as a prerequisite, hold the mutex (meaning, that thread has previously called lock()
on it), or else the program exhibits undefined behavior. This is true whether you call unlock
explicitly, or trick some helper like unique_lock
into calling it for you.
鉴于这一切,将 unique_lock
实例移动到另一个线程仅仅是触发未定义行为的方法;没有上升。
In light of all this, moving a unique_lock
instance over to another thread is merely a recipe for triggering undefined behavior shortly thereafter; there is no upside.
这篇关于移动unique_lock< recursive_mutex>到另一个线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!