将unique_lock <recursive_mutex>移动到另一个线程

时间:2016-07-18 13:44:46

标签: c++ c++11 c++14 stdthread recursive-mutex

我想知道当你移动一个unique_lock的{​​{1}}时会发生什么。

具体来说,我正在看这段代码:

recursive_mutex

此示例代码的输出让我感到非常惊讶。 main()中的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! } 如何知道线程释放了互斥锁?这是真的吗?

1 个答案:

答案 0 :(得分:4)

您似乎将某些魔法属性归因于unique_lock。它没有任何东西,它是一个非常简单的类。它有两个数据成员Mutex* pmbool owns(仅为展示显示成员名称)。 lock()只是pm->lock(); owns = true;unlock执行pm->unlock(); owns = false;。析构函数是if (owns) unlock();。将构造函数副本移动到两个成员上,并相应地将它们设置为原始文件nullptrfalseowns_lock()会返回owns成员的值。

所有线程同步魔法都在互斥锁本身及其lock()unlock()方法中。 unique_lock只是它周围的薄包装。

现在,作为先决条件,调用mutex.unlock()的线程必须持有互斥锁(意味着该线程先前已在其上调用lock()),否则程序将显示未定义的行为。无论您是明确地调用unlock,还是像unique_lock那样使用某个帮助来为您调用它,都是如此。

鉴于这一切,将unique_lock实例移动到另一个线程仅仅是此后不久触发未定义行为的一个方法;没有好处。