移动unique_lock< recursive_mutex>到另一个线程 [英] Moving a unique_lock<recursive_mutex> to another thread

查看:282
本文介绍了移动unique_lock< recursive_mutex>到另一个线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道当你移动包含 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&lt; recursive_mutex&gt;到另一个线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆