C++多執行緒系列(C++11)-uniqu_lock(四)
阿新 • • 發佈:2018-12-21
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; }