C++多线程快速入门(二)共享数据同步以及数据竞争
目錄
- std::unique_lock類模板
- 僅調用一次
- 線程局部存儲
- 原子變量
- 往期內容回顧
std::unique_lock類模板
互斥鎖保證了線程間的同步,卻將并行操作變成了串行操作,對性能有較大影響,所以我們要盡可能減小鎖的區間粒度。
lock_guard只能保證在析構的時候進行解鎖操作,所以其本身并沒有提供加鎖解鎖的接口
上面代碼中,sharedPrint函數內部有兩段代碼需要進行加鎖保護,此時使用lock_guard就需要創建兩個局部對象來管理同一個互斥鎖。
其實可以使用unique_lock,它提供了**lock()和unlock()**接口,能記錄現在處于上鎖還是沒上鎖狀態,在析構的時候,會根據當前狀態來決定是否要進行解鎖(lock_guard就一定會解鎖)
僅調用一次
程序免不了要初始化數據,線程并發沒有某種同步手段來控制,會導致初始化函數多次運行。
c++11種提供僅調用一次的功能,首先聲明一個once_flag類型的變量作為初始化標志,最好是靜態、全局的,這樣對于線程就是可見的了。然后調用專門的call_once()函數,以函數式編程的方式,傳遞這個標志和初始化函數,這樣就可以保證,即使多個線程重入call_once(),也只能由一個線程會成功初始化
#include <iostream> #include <thread> #include <mutex>// 全局的初始化標志 static std::once_flag flag; auto f = []() {std::call_once(flag,[](){std::cout << "only once" << std::endl;}); }; int main() {// 啟動兩個線程,運行函數fstd::thread t1(f);std::thread t2(f);t1.join();t2.join();// std::cout << "finished" << std::endl;return 0; }實際編譯結果如下:
only once線程局部存儲
當讀寫全局變量時,一般也會出現數據競爭,但是全局變量不一定是必須共享的,可能僅僅是為了方便線程傳入傳出數據,不是共享所有權。此時可以使用關鍵字thread_local實現線程局部緩存,被其標志的變量在每個線程里都會有一個獨立的副本。
#include <iostream> #include <thread>int main() {// 啟動兩個線程,運行函數fthread_local int n = 0;auto f = [&](int x){n += x;std::cout << n << std::endl;};std::thread t1(f, 10);std::thread t2(f, 20);t1.join();t2.join();// std::cout << "finished" << std::endl;return 0; }結果是:
10 20說明兩個線程互不干擾,如果將變量聲明改為static,兩個線程會共享這個變量,導致連續加兩次,結果是下面:
10 or 20 30 30原子變量
對于非獨占、必須共享的數據,要保證多線程讀寫共享數據一致就要解決同步問題,兩個線程得互斥。但是mutex互斥量成本較高,可以使用atmoic原子化操作。
int main() {static std::atomic_flag flag {false}; // 原子化的標志量static atomic_int n; // 原子化的intauto f = [&](){auto value = flag.test_and_set(); // TAS檢查原子標志量if (value) {std::cout << "flag has been set" << std::endl;} else {std::cout << "set flag by" << std::this_thread::get_id() << std::endl; // 輸出線程id}n += 100; // 原子變量加法運算std::this_thread::sleep_for(std::chrono::seconds(5)); //線程睡眠std::cout << n << std::endl;};std::thread t1(f);std::thread t2(f);t1.join();t2.join(); }往期內容回顧
C++多線程快速入門(一):基本&常用操作
總結
以上是生活随笔為你收集整理的C++多线程快速入门(二)共享数据同步以及数据竞争的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 颐和园夏天几点开门
- 下一篇: 商业计划书多少钱啊?