首先我们给出一段代码
#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;
}