多线程的使用方式
文章目錄
- 1 創建線程
- 2 傳遞參數給線程入口函數
- 3 鎖與臨界區
- 4 自解鎖
- 5 原子操作
1 創建線程
這里我們直接使用C++11提供的庫函數來進行實現。
簡單示例代碼如下:
#include<iostream> #include<thread> using namespace std;void workFun() {for (int n = 0; n < 4; n++)cout << "Hello,other thread." << endl; }//搶占式int main() {thread t(workFun);t.detach();//t.join();for (int n = 0; n < 4; n++)cout << "Hello,main thread." << endl;while (true){}return 0; }需要注意的幾個點:
- main線程結束,整個進程執行結束,其它附屬線程也隨之結束。
- 使用join()的話,主線程會等其它線程執行完才繼續執行;而使用detach()則并行執行。
2 傳遞參數給線程入口函數
測試代碼如下:
#include<iostream> #include<thread> using namespace std;void workFun(int index) {for (int n = 0; n < 4; n++)cout << index << "Hello,other thread." << endl; }//搶占式int main() {thread t[4];for (int n = 0; n < 4; n++){t[n] = thread(workFun,n);}for (int n = 0; n < 4; n++){t[n].join();//t[n].detach();}for (int n = 0; n < 4; n++)cout << "Hello,main thread." << endl;while (true){}return 0; }對于線程數組來說,我們使用join各個線程之間是可以并行運行的。如果有多個線程對象,我們只調用了一個線程對象的join方法,那么所有的線程都會以join的方式執行,就表現為并行執行。但是,在程序執行結束前所有的線程對象都需要調用一次join方法(只能調用一次),否則程序會出現異常。
3 鎖與臨界區
在上面的代碼中我們多個線程中,cout屬于共享資源,在輸出的時候很容易出問題。我們這里使用一下鎖,保證共享資源的安全性。代碼如下:
#include<iostream> #include<thread> using namespace std;void workFun(int index) {for (int n = 0; n < 4; n++)cout << index << "Hello,other thread." << endl; }//搶占式int main() {thread t[4];for (int n = 0; n < 4; n++){t[n] = thread(workFun,n);}for (int n = 0; n < 4; n++){t[n].join();//t[n].detach();}for (int n = 0; n < 4; n++){//臨界區域-開始m.lock();cout << "Hello,main thread." << endl;m.unlock();//臨界區域-結束}while (true){}return 0; }4 自解鎖
為了防止上鎖后沒解鎖,于是誕生了自解鎖,原理和智能指針類似。
示例代碼:
mutex m;int sum = 0; void workFun(int index) {for (int n = 0; n < 20000000; n++){//自解鎖lock_guard<mutex> lg(m);//臨界區域-開始//m.lock();sum++;//m.unlock();//臨界區域-結束} }//搶占式自解鎖源碼:
// CLASS TEMPLATE lock_guard template <class _Mutex> class lock_guard { // class with destructor that unlocks a mutex public:using mutex_type = _Mutex;explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock_MyMutex.lock();}lock_guard(_Mutex& _Mtx, adopt_lock_t) : _MyMutex(_Mtx) { // construct but don't lock}~lock_guard() noexcept {_MyMutex.unlock();}lock_guard(const lock_guard&) = delete;lock_guard& operator=(const lock_guard&) = delete;private:_Mutex& _MyMutex; };5 原子操作
對于一些基本類型,我們可以將其定義為原子類型,避免作為共享資源運算時需要使用鎖。原子類型相對于鎖,性能有很大的提升。
示例代碼如下:
#include<iostream> #include<thread> #include<mutex>//鎖 #include<atomic>//原子 #include"CELLTimestamp.hpp" using namespace std; //原子操作 原子 分子 mutex m; const int tCount = 4; atomic_int sum = 0; void workFun(int index) {for (int n = 0; n < 20000000; n++){//自解鎖//lock_guard<mutex> lg(m);//臨界區域-開始//m.lock();sum++;//m.unlock();//臨界區域-結束}//線程安全 線程不安全//原子操作 計算機處理命令時最小的操作單位//cout << index << "Hello,main thread." << n << endl; }//搶占式int main() {thread t[tCount];for (int n = 0; n < tCount; n++){t[n] = thread(workFun, n);}CELLTimestamp tTime;for (int n = 0; n < tCount; n++){t[n].join();//t[n].detach();}cout << tTime.getElapsedTimeInMilliSec() << ",sum=" << sum << endl;sum = 0;tTime.update();for (int n = 0; n < 80000000; n++){sum++;}cout << tTime.getElapsedTimeInMilliSec() << ",sum=" << sum << endl;cout << "Hello,main thread." << endl;return 0; }參考資料:
總結
- 上一篇: 民间借贷合法利息几分
- 下一篇: 索引文件核心头文件定义