c++中的多线程
使用 std::thread 時需要包含?#include<thread>?頭文件,定義了表示線程的類、用于互斥訪問的類與方法等。
參考網址:
- https://blog.csdn.net/liuker888/article/details/46848905
- https://blog.csdn.net/fengbingchun/article/details/73393229
成員類型和成員函數:
std::thread中主要聲明三類函數:(1)、構造函數、拷貝構造函數(拷貝構造函數被禁用,意味著thread不可被拷貝構造,但能被轉移(move)或者互換(swap))及析構函數;(2)、成員函數;(3)、靜態成員函數(hardware_concurrency,檢測硬件并發特性。
構造函數如下:
一些相關的數據結構和存儲位置:
//棧上 thread t1(show); //根據函數初始化執行 thread t2(show); thread t3(show); //線程數組 thread th[3]{thread(show), thread(show), thread(show)}; //堆上 thread *pt1(new thread(show)); thread *pt2(new thread(show)); thread *pt3(new thread(show)); //線程指針數組 thread *pth(new thread[3]{thread(show), thread(show), thread(show)});線程初始化(如下實現了多線程傳遞參數)
void show(const char *str, const int id); int main() { thread t1(show, "hello!", 0); //三個參數分別為函數名,以及其兩個參數thread t2(show, "C++!", 1); return 0; }join:調用該函數會阻塞當前線程。阻塞調用者(caller)所在的線程直至被join的std::thread對象標識的線程執行結束;
detach:將當前線程對象所代表的執行實例與該線程對象分離,使得線程的執行可以單獨進行。一旦線程執行完畢,它所分配的資源將會被釋放。
- 在任何一個時間點上,線程是可結合的(joinable),或者是分離的(detached)。一個可結合的線程能夠被其他線程收回其資源和殺死;在被其他線程回收之前,它的存儲器資源(如棧)是不釋放的。相反,一個分離的線程是不能被其他線程回收或殺死的,它的存儲器資源在它終止時由系統自動釋放。
- threads.joinable()?判斷線程是否可以join? ? ?;threads.join();//主線程等待當前線程執行完成再退出 ; th.detach();
//脫離主線程的綁定,主線程掛了,子線程不報錯,子線程執行完自動退出。??//detach以后,子線程會成為孤兒線程,線程之間將無法通信。?
---------------------------------
獲取CPU核心個數:
n = thread::hardware_concurrency();//獲取cpu核心個數原子變量與線程安全:線程之間會有沖突(下面的代碼可能存在num++重疊的現象)
- 互斥量:
存在問題:計算速度很慢,原因主要是互斥量加解鎖需要時間 。std::mutex。
- 原子變量:
通過原子變量后運算結果正確,計算速度一般。參考std::atomic
但其實只要使用join,可以提升計算的速度
thread t1(run); t1.join(); //結束才回到主線程thread t2(run); t2.join();------------------------
時間等待的問題
#include<iostream> #include<thread> #include<chrono> using namespace std; int main() { thread th1([]() { //讓線程等待3秒 this_thread::sleep_for(chrono::seconds(3)); //讓cpu執行其他空閑的線程 this_thread::yield(); //線程id cout << this_thread::get_id() << endl; }); return 0; }- yield()函數可以用來將調用者線程跳出運行狀態,重新交給操作系統進行調度,即當前線程放棄執行,操作系統調度另一線程繼續執行;
- sleep_until()函數是將線程休眠至某個指定的時刻(time point),該線程才被重新喚醒;
- sleep_for()函數是將線程休眠某個指定的時間片(time span),該線程才被重新喚醒,不過由于線程調度等原因,實際休眠實際可能比sleep_duration所表示的時間片更長。
-------------------------------
線程的交換使用 swap(t1,?t2);
線程移動使用thread?t2?=?move(t1);
轉載于:https://www.cnblogs.com/zhang-qc/p/8671248.html
總結
- 上一篇: keras中的mini-batch gr
- 下一篇: 线程安全的单例模式C++实现