2017-04-19 117 views
-1

我正在阅读二进制信号量和互斥量(Difference between binary semaphore and mutex)之间的差异,我想验证的一件事是,当一个任务锁定(获取)互斥锁时,只有它可以解锁(释放)它。如果另一个任务试图解锁它没有锁定的互斥锁(因此不拥有),那么会遇到错误条件,最重要的是,互斥锁未解锁,并且我在C++ 14代码下创建了这个互斥锁:std :: mutex如何在不同的线程中解锁?

#include <iostream> 
#include <thread> 
#include <mutex> 
#include <chrono> 
using namespace std; 

int counter; 
int i; 
std::mutex g_pages_mutex; 
void increment() 
{ 
    std::cout<<"increment...."<<std::endl;  
    g_pages_mutex.lock(); 
    bool flag = g_pages_mutex.try_lock(); 
    std::cout<<"increment Return value is "<<flag<<std::endl; 
    counter++; 
    std::this_thread::sleep_for(5s); 
} 
void increment1() 
{ 
    std::this_thread::sleep_for(5s);  
    std::cout<<"increment1...."<<std::endl;  
    g_pages_mutex.unlock();  
    counter++; 
    bool flag = g_pages_mutex.try_lock(); 
    std::cout<<"increment1 Return value is "<<flag<<std::endl; 
} 
int main() 
{ 
    counter = 0; 
    std::thread t(increment); 
    std::thread t1(increment1); 
    t.join(); 
    t1.join(); 
    return 0; 
} 

但是这个例子我能解开从线程互斥体不拥有这一点,所以只是想有一些了解的差距还是这个问题在C++ 14的std ::互斥?

+0

http://en.cppreference.com/w/cpp/thread/mutex/unlock – Mat

+0

[std :: mutex :: unlock描述]的开头语句(http://en.cppreference。 com/w/cpp/thread/mutex/unlock)非常明了。 *“互斥量必须被当前执行线程锁定,否则,行为是不确定的。”* – WhozCraig

回答

3

std::mutex调用try_lock(不递归)调用线程拥有,不拥有互斥调用unlock通过调用线程,并在持有互斥锁时结束线程,都会导致未定义的行为。

它可能会成功,它可能会失败并抛出一个异常,它可能会格式化您的硬盘驱动器,它可能召唤恶魔,它可能会时间旅行和纠正您的代码,或者它可能会做别的。就标准而言,任何东西都是允许的。

-1

cppreference std::mutex(重点煤矿):

如果同时还通过任何线程,同时拥有互斥或线程终止时所拥有的互斥体被破坏程序的行为是不确定的。

从同一网站上std::mutex::try_lockTC points out in their answer

如果try_lock是由已经拥有互斥线程调用的,行为是不确定的。

而且还std::mutex::unlockTC points out in their answer

互斥量必须执行的当前线程被锁定,否则,行为是不确定的。

无论你的函数和线程导致未定义的行为:

  1. increment电话lock()然后try_lock():未定义行为
  2. increment1电话unlock()拥有互斥前:未定义行为

删除try_lock()从如果在线程结束之前不呼叫unlock(),则仍然会导致未定义的行为。

你应该更喜欢使用std::lock_guard,或者一个简单的int你也可以使用std::atomic

+0

我怀疑这有什么问题,但如果我知道它是什么,我会被诅咒的。 – Tas

0

用于调用unlock的前提条件是保持该互斥的所有权,根据(STD)30.4.1.2:

表达m.unlock()应被良好形成并且具有以下语义:

要求:调用线程应拥有互斥量。

由于执行线程increment1不具有互斥量的所有权,因此它引爆了未定义的行为。

相关问题