std::lock_guard 是遵循 RAII
RAII
RAII技術被認爲是C++中管理資源的最佳方法,進一步引申,使用RAII技術也可以實現安全、簡潔的狀態管理,編寫出優雅的異常安全的代碼。
資源管理
RAII是C++的發明者Bjarne Stroustrup提出的概念,RAII全稱是“Resource Acquisition is Initialization”,直譯過來是“資源獲取即初始化”,也就是說在構造函數中申請分配資源,在析構函數中釋放資源。因爲C++的語言機制保證了,當一個對象創建的時候,自動調用構造函數,當對象超出作用域的時候會自動調用析構函數。所以,在RAII的指導下,我們應該使用類來管理資源,將資源和對象的生命週期綁定。
看一段簡單的代碼:
#include <iostream>
#include <mutex>
#include <thread>
/* global */
int g_i = 0;
std::mutex g_mutex;
void g_increment()
{
g_mutex.lock();
++g_i;
std::cout <<"thread_id:"<<std::this_thread::get_id() <<",g_i:" << g_i << std::endl;
if(XXX)
return;
g_mutex.unlock();
}
int main()
{
std::cout << "mian g_i:" << g_i << std::endl;
std::thread threads[10];
for (auto i = 0; i < 10; i++)
threads[i] = std::thread(g_increment);
for (auto &t : threads)
t.join();
system("pause");
}
mutex 要手動的 lock 和 unlock
如果 我們上面執行了
if(XXX)
return;
或者有異常執行了 return
那麼其他的線程就要排隊 等待unlock
比如這樣
只有第一個線程執行了 return了 沒unlock 後面的線程都在等。
我們可以用 std::lock_guard 代替
當 離開作用域時會自動的釋放, 不用我們在每個地方都寫 unlock
#include <iostream>
#include <mutex>
#include <thread>
/* global */
int g_i = 0;
std::mutex g_mutex;
void g_increment()
{
std::lock_guard<std::mutex> lock(g_mutex);
++g_i;
std::cout <<"thread_id:"<<std::this_thread::get_id() <<",g_i:" << g_i << std::endl;
/// 離開作用域就會被釋放
}
int main()
{
std::cout << "mian g_i:" << g_i << std::endl;
std::thread threads[10];
for (auto i = 0; i < 10; i++)
threads[i] = std::thread(g_increment);
for (auto &t : threads)
t.join();
system("pause");
}
10個線程都執行了