将锁定的std :: unique_lock移交给新线程

时间:2017-05-26 17:49:35

标签: c++ visual-studio-2015 c++14 language-lawyer mutex

考虑以下示例,我创建std::mutex,锁定它,然后将锁定交给另一个线程:

#include <future>
#include <mutex>

int main()
{
    // Create and lock a mutex
    std::mutex mutex;
    std::unique_lock<decltype(mutex)> lock(mutex);

    // Hand off the lock to another thread
    auto promise = std::async(std::launch::async, 
        [lock{ std::move(lock) }]() mutable
        {
            // Unlock the mutex
            lock.unlock();
        });

    promise.get();

    return 0;
}

该示例似乎与gcc 6.3运行良好,但在Visual Studio 2015中运行时断言失败,错误“解锁无主互斥锁”

我注意到,如果我将示例切换为使用std::shared_timed_mutexstd::shared_lock,则示例将成功完成。我还注意到,如果我删除显式unlock,那么示例成功完成,但是互斥锁似乎根本没有解锁(如果我再次尝试锁定互斥锁,则与VC崩溃,gcc不会抱怨)。

根据我在cppreference.com上关于std::unique_lock的内容,我觉得原来的例子应该运行正常。如果另一个帖子执行std::mutexstd::unique_lockunlock的某些内容是否禁止某个帖子转到lock?这可能是VC的错误吗?

1 个答案:

答案 0 :(得分:7)

根据http://en.cppreference.com/w/cpp/thread/mutex/unlock

  

互斥锁必须由当前执行线程锁定,否则行为未定义。

std::shared_timed_mutex::unlock()的文档具有相同的规范,因此无法保证与该类一起使用。