std::thread单个线程永久持有锁

最近打算写一个curl的C++11封装,使用Thread的时候出现了一个BUG,某一个线程始终持有一个锁,反复加锁解锁的过程。而另外一个线程卡死在lock上。大致代码如下:

std::mutex mtx;

//Thread 1

mtx.lock();

//...do something

mtx.unlock();


//Thread 2

do {

    mtx.lock();

    //...do something

    mtx.unlock();

}while(true);

Thread 2在一个死循环内持有并加解锁。另外一个是普通的流程函数。

代码没有抛出异常导致死锁,起初以为是自己mutex不熟,用法有误,但是反复查证,用法应该没问题。并且奇妙的是如果在加锁前和解锁后打印日志就会正常。

难道是死循环导致的吗?

于是在Thread 2的unlock之后加了一句usleep:

mtx.unlock();

usleep(0);

在零X年的时候看过一篇帖子,说sleep(0)可以让线程放弃当前获得的cpu时间片。理论上这样就可以产生一个中断,让其他线程得到执行。

结果并没有变化。

难道那篇帖子说的不对么。又改了下:

mtx.unlock();

usleep(1);

结果正常了,2个线程都正确的加锁解锁。

事后总结,猜测就是因为Thread 2在解锁之后,再次加锁之前没有能够产生中断的函数,于是很快地又再次获得了锁,导致其他线程总是无法获得锁。这个问题和自旋锁在单核机器上无法正常工作是一个原理。

你可能感兴趣的:(std::thread单个线程永久持有锁)