一般来讲,一个线程加锁,另一个线程解锁,是很容易死锁的。
产生死锁的四个必要条件:
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
写了一个读写锁,debug模式下运行一直出错。在下边代码22行处,提示信息: unlock a unowened lock。是这样的,mutex_write在不同的线程处加锁和解锁,在debug模式下,编译器会查找在不同线程加锁解锁的情况并出错。
解决办法:release模式下就好了。。
class read_write_lock
{
private:
mutex mutex_read;
mutex mutex_write;
int count;
public:
read_write_lock() :count(0) {}
void read_lock()
{
mutex_read.lock();
count++;
if (count == 1)
mutex_write.lock();
mutex_read.unlock();
}
void read_unlock()
{
mutex_read.lock();
count--;
if (count == 0)
mutex_write.unlock();
mutex_read.unlock();
}
void write_lock()
{
mutex_write.lock();
}
void write_unlock()
{
mutex_write.unlock();
}
};
class rwlock_test
{
private:
string str;
read_write_lock rwlock;
public:
rwlock_test() :str("str") {}
void read()
{
rwlock.read_lock();
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 1900 + 100));
cout << "read " << str << endl;
rwlock.read_unlock();
}
void write()
{
rwlock.write_lock();
str += "_str";
cout << "write " << str << endl;
rwlock.write_unlock();
}
void start()
{
int count = 5;
vector<thread*> vt(2 * count);
for (int i = 0; i < count; i++)
{
vt[i] = new thread(bind(&rwlock_test::read, this));
}
for (int i = count; i < 2 * count; i++)
{
vt[i] = new thread(bind(&rwlock_test::write, this));
}
for (auto x : vt)
x->join();
}
};