C++線程之thread詳解
1.創(chuàng)建線程
直接初始話thread
類對象進(jìn)行創(chuàng)建線程,創(chuàng)建線程后調(diào)用join()
方法,讓主線程等待子線程完成工程。
#include <iostream> #include <thread> void thread_function() { std::cout << "thread function\n"; } int main() { std::thread t(&thread_function); // t starts running std::cout << "main thread\n"; t.join(); // main thread waits for the thread t to finish return 0; }
2.守護(hù)線程
我們可以調(diào)用detach()
方法,將線程變?yōu)槭刈o(hù)線程,完成線程和主線程的分離。一旦線程分離,我們不能強(qiáng)迫它再次加入主線程,再次調(diào)用join()
方法會報錯的。
一旦分離,線程應(yīng)該永遠(yuǎn)以這種方式存在。調(diào)用join()
函數(shù)之前可以使用函數(shù)joinable()
檢查線程是否可以加入主線程,加強(qiáng)程序健壯性。
// t2.cpp int main() { std::thread t(&thread_function); std::cout << "main thread\n"; if( t.joinable( ) ) // t.join(); // t.join(); t.detach(); return 0; }
3. 可調(diào)用對象
線程可以調(diào)用
- 函數(shù)指針
- 類對象
- lamda表達(dá)式
1.函數(shù)指針
就像之前舉例的樣子
2.類對象
#include <iostream> #include <thread> class MyFunctor { public: void operator()() { std::cout << "functor\n"; } }; int main() { MyFunctor fnctor; // 這樣是不能運行的, // std::thread t(fnctor); // 必須按照這樣進(jìn)行初始話。 // MyFunctor fnctor; Note that we had to add () to enclose the MyFunctor(). std::thread t((MyFunctor())); // it's related to the function declaration convention in C++. std::cout << "main thread\n"; t.join(); return 0; }
3.lamda表達(dá)式
#include <iostream> #include <thread> class MyFunctor { public: void operator()() { std::cout << "functor\n"; } }; int main() { MyFunctor fnctor; // 這樣是不能運行的, // std::thread t(fnctor); // 必須按照這樣進(jìn)行初始話。 // MyFunctor fnctor; Note that we had to add () to enclose the MyFunctor(). std::thread t((MyFunctor())); // it's related to the function declaration convention in C++. std::cout << "main thread\n"; t.join(); return 0; }
4. 傳參
傳參分為三種
1.值傳遞
2.引用傳遞
3.不復(fù)制,也不共享內(nèi)存的傳參方式move()
#include <iostream> #include <thread> #include <string> void thread_function(std::string s) { std::cout << "thread function "; std::cout << "message is = " << s << std::endl; } int main() { std::string s = "Kathy Perry"; // 1. 值傳遞 std::thread t(&thread_function, s); // 2. 引用傳遞 std::thread t(&thread_function, std::ref(s)); // 3. 不復(fù)制,也不共享內(nèi)存的傳參方式`move() std::thread t(&thread_function, std::move(s)); std::cout << "main thread message = " << s << std::endl; t.join(); return 0; }
5. 線程的移動和復(fù)制
// t5.cpp #include <iostream> #include <thread> void thread_function() { std::cout << "thread function\n"; } int main() { std::thread t(&thread_function); std::cout << "main thread\n"; // transfer the ownership of the thread by moving it: std::thread t2 = move(t); t2.join(); return 0; }
6.線程id
獲取線程的id: this_thread::get_id()
總共有多少個線程:std::thread::hardware_concurrency()
程序
int main() { std::string s = "Kathy Perry"; std::thread t(&thread_function, std::move(s)); std::cout << "main thread message = " << s << std::endl; std::cout << "main thread id = " << std::this_thread::get_id() << std::endl; std::cout << "child thread id = " << t.get_id() << std::endl; t.join(); return 0; }
輸出
thread function message is = Kathy Perry
main thread message =
main thread id = 1208
child thread id = 5224
7. 互斥mutex
互斥鎖可能是 C++ 中使用最廣泛的數(shù)據(jù)保護(hù)機(jī)制,但重要的是構(gòu)造我們的代碼以保護(hù)正確的數(shù)據(jù)并避免接口中固有的競爭條件。互斥鎖也有自己的問題,表現(xiàn)為死鎖和保護(hù)太多或太少的數(shù)據(jù)
標(biāo)準(zhǔn) C++ 庫提供了std::lock_guard
類模板,它實現(xiàn) 了互斥鎖的RAII
習(xí)慣用法。它在構(gòu)造時鎖定提供的互斥鎖并在銷毀時解鎖它,從而確保始終正確解鎖鎖定的互斥鎖。
#include <iostream> #include <thread> #include <list> #include <algorithm> #include <mutex> using namespace std; // a global variable std::list<int>myList; // a global instance of std::mutex to protect global variable std::mutex myMutex; void addToList(int max, int interval) { // the access to this function is mutually exclusive std::lock_guard<std::mutex> guard(myMutex); for (int i = 0; i < max; i++) { if( (i % interval) == 0) myList.push_back(i); } } void printList() { // the access to this function is mutually exclusive std::lock_guard<std::mutex> guard(myMutex); for (auto itr = myList.begin(), end_itr = myList.end(); itr != end_itr; ++itr ) { cout << *itr << ","; } } int main() { int max = 100; std::thread t1(addToList, max, 1); std::thread t2(addToList, max, 10); std::thread t3(printList); t1.join(); t2.join(); t3.join(); return 0; }
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C語言實現(xiàn)學(xué)生宿舍信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)學(xué)生宿舍信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03C語言設(shè)計圖書登記系統(tǒng)與停車場管理系統(tǒng)的實例分享
這篇文章主要介紹了C語言設(shè)計圖書登記系統(tǒng)與停車場管理系統(tǒng)的實例分享,重在以最簡單的一些需求來展示管理系統(tǒng)的設(shè)計思路,需要的朋友可以參考下2016-06-06C++實現(xiàn)Window環(huán)境聊天室功能
這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)Window環(huán)境聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-06-06