C++学习笔记之线程:数据共享与竞争,线程死锁

首先我们给出一段代码
#include <iostream>
#include <thread>
#include <mutex>
#include <fstream>
#include <string>
using namespace std;
class LogFile
{
public:
	LogFile()
	{
		data = 0;
		f.open("log.txt");
	}
	void printfile(string id,int value)
	{
		//lock_guard<mutex> locker(m_mutex);
		//m_mutex.lock();
		f << "From " << id <<": " << value << "------"<< data << endl;
		for(int j = 0; j < 2; j++) data += 1;
		//m_mutex.unlock();
	}
private:
	ofstream f;
	int data;
	mutex m_mutex;
};
void fun(LogFile &log)
{
	for(int i = 0; i < 10; i++)
	{
		log.printfile("t1",i);
	}
}
int main()
{
	LogFile log;
	thread t1(fun,ref(log));
	for(int i = 0; i < 10; i++)
	{
		log.printfile("t2",i);
	}
	t1.join();
    return 0;
}

代码运行结果的log.txt文件为

 第一次运行      第二次运行

由结果我们看出两次运行结果不同,正常最后的data应该为38,从上述运行结果看出与我们期望的不同,这就是在数据共享条件下出现的竞争,当两个进程同时出现时便可能会对共享数据的内存只执行一次,于是就出现了上述结果,为了解决这个问题,下面提出两种方法,一种是lock,与unlock方法,对进程加锁,这种方法有一个致命的问题就是在lock期间如果出现异常,则会一直被锁住,还有一个就是采用

lock_guard<mutex> locker(m_mutex);

这个就能解决lock与unlock的问题

	void printfile(string id,int value)
	{
		//lock_guard<mutex> locker(m_mutex);
		m_mutex.lock();
		f << "From " << id <<": " << value << "------"<< data << endl;
		for(int j = 0; j < 2; j++) data += 1;
		m_mutex.unlock();
	}


void printfile(string id,int value)
	{
		lock_guard<mutex> locker(m_mutex);
		//m_mutex.lock();
		f << "From " << id <<": " << value << "------"<< data << endl;
		for(int j = 0; j < 2; j++) data += 1;
		//m_mutex.unlock();
	}


二,线程死锁

#include <iostream>
#include <thread>
#include <mutex>
#include <fstream>
#include <string>
using namespace std;
class LogFile
{
public:
	LogFile()
	{
		data = 0;
		f.open("log.txt");
	}
	void printfile(string id,int value)
	{
		lock_guard<mutex> locker(m_mutex);
		lock_guard<mutex> locker2(m_mutex2);
		f << "From " << id <<": " << value << "------"<< data << endl;
		for(int j = 0; j < 2; j++) data += 1;
	}
	void printfile2(string id,int value)
	{
		lock_guard<mutex> locker2(m_mutex2);
		lock_guard<mutex> locker(m_mutex);
		
		f << "From " << id <<": " << value << "------"<< data << endl;
		for(int j = 0; j < 2; j++) data += 1;
	}
private:
	ofstream f;
	int data;
	mutex m_mutex;
	mutex m_mutex2;
};
void fun(LogFile &log)
{
	for(int i = 0; i < 100; i++)
	{
		log.printfile2("t1",i);
	}
}
int main()
{
	LogFile log;
	thread t1(fun,ref(log));
	for(int i = 0; i < 100; i++)
	{
		log.printfile("t2",i);
	}
	t1.join();
    return 0;
}

结果如下

mutex与mutex2交替执行当它们同时锁住后互相等待彼此解锁,由此便引发了死锁

解决方法为:

	void printfile(string id,int value)
	{
		lock_guard<mutex> locker(m_mutex);
		lock_guard<mutex> locker2(m_mutex2);
		f << "From " << id <<": " << value << "------"<< data << endl;
		for(int j = 0; j < 2; j++) data += 1;
	}
	void printfile2(string id,int value)
	{
		
		lock_guard<mutex> locker(m_mutex);
		lock_guard<mutex> locker2(m_mutex2);
		f << "From " << id <<": " << value << "------"<< data << endl;
		for(int j = 0; j < 2; j++) data += 1;
	}

或者用lock()指定锁的顺序

	void printfile(string id,int value)
	{
		lock(m_mutex,m_mutex2);
		lock_guard<mutex> locker(m_mutex,adopt_lock);
		lock_guard<mutex> locker2(m_mutex2,adopt_lock);
		f << "From " << id <<": " << value << "------"<< data << endl;
		for(int j = 0; j < 2; j++) data += 1;
	}
	void printfile2(string id,int value)
	{
		lock(m_mutex,m_mutex2);
		lock_guard<mutex> locker2(m_mutex2,adopt_lock);
		lock_guard<mutex> locker(m_mutex,adopt_lock);
		
		f << "From " << id <<": " << value << "------"<< data << endl;
		for(int j = 0; j < 2; j++) data += 1;
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值