Data 2018/11/12 Add By WJB
在多线程中,有时候会出现一个方法中又一断或者多段代码需要加锁,但是并非整个方法代码加锁,那么我们就需要一个灵活的锁-unique_lock;说明:unique_lock会降低代码执行效率,不推荐使用。
我们接着上一篇文中的的代码讲解unique_lock的使用方法。
class LogFile{
public:
LogFile(std::string filepath)
{
f.open(filepath);
}
~LogFile()
{
if (f.is_open())
{
f.close();
}
}
public:
void Print_string(string & msg,int id)
{
lock_guard<mutex> gurd(m_Mutex);
f << msg <<"ID:"<<id<< endl;
}
private:
mutex m_Mutex;
fstream f;
};
1,在LogFile的Print_string(),整个方法的代码都被加锁。如果使用unique_lock,做如下修改:
Exap1
void Print_string(string & msg,int id)
{
unique_lock <mutex> uniqelocker(m_Mutex);
f << msg <<"ID:"<<id<< endl;
uniqelocker.unlock();
{
//其他不要加锁代码
}
}
Exap2
void Print_string(string & msg,int id)
{
unique_lock <mutex> uniqelocker(m_Mutex,std::defer_lock);
f << msg <<"ID:"<<id<< endl;
{
//其他不要加锁代码
}
uniqelocker.lock();
{
//需要加锁代码
}
uniqelocker.unlock();
{
//其他不要加锁代码
}
uniqelocker.lock();
{
//需要加锁代码
}
uniqelocker.unlock();
}
这样修改后,示例1对lock后一部分代码进行加锁,示例2可以对多短不相连代码加锁
2,unique_lock 不可以被复值,只能move()
mutex m_Mutex;
unique_lock <mutex> uniqelocker(m_Mutex)
unique_lock <mutex> uniqelocker2=std::move(uniqelocker);
这样移动后,uniqelocker失去了对m_Mutex的控制权,uniqelocker2获得了控制权。
3,给出所有代码,注意工程是VS2015 C++ win32 控制台程序
#include <thread>
#include <iostream>
#include <string.h>
#include <string>
#include <mutex>
#include <fstream>
using namespace std;
mutex m_mutex;
class LogFile{
public:
LogFile(std::string filepath)
{
f.open(filepath);
}
~LogFile()
{
if (f.is_open())
{
f.close();
}
}
public:
void Print_string(string & msg,int id)
{
unique_lock <mutex> uniqelocker(m_Mutex,std::defer_lock);
f << msg <<"ID:"<<id<< endl;
{
//其他不要加锁代码
}
uniqelocker.lock();
{
//需要加锁代码
}
uniqelocker.unlock();
{
//其他不要加锁代码
}
uniqelocker.lock();
{
//需要加锁代码
}
uniqelocker.unlock();
}
private:
mutex m_Mutex;
fstream f;
};
void Function_1(LogFile& logfile)
{
for (int i = 0; i > -100; i--)
{
string str = "my name is multithread!\n";
logfile.Print_string(str, i);
}
}
int main()
{
LogFile logfile("logfile.txt");
thread mythread(Function_1,std::ref(logfile));
for (int i = 0; i <100; i++)
{
string str = "this is mainthread!\n";
logfile.Print_string(str,i);
}
mythread.join(); //阻塞式
return 0;
}
上一篇文章连接:https://blog.youkuaiyun.com/wangjianbo09/article/details/83786086