C++線程之thread詳解
1.創(chuàng)建線程
直接初始話thread類對(duì)象進(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()方法會(huì)報(bào)錯(cuò)的。
一旦分離,線程應(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)用對(duì)象
線程可以調(diào)用
- 函數(shù)指針
- 類對(duì)象
- lamda表達(dá)式
1.函數(shù)指針
就像之前舉例的樣子
2.類對(duì)象
#include <iostream>
#include <thread>
class MyFunctor
{
public:
void operator()() {
std::cout << "functor\n";
}
};
int main()
{
MyFunctor fnctor;
// 這樣是不能運(yùn)行的,
// 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;
// 這樣是不能運(yùn)行的,
// 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. 線程的移動(dòng)和復(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()
總共有多少個(gè)線程: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ù)并避免接口中固有的競(jìng)爭(zhēng)條件?;コ怄i也有自己的問(wèn)題,表現(xiàn)為死鎖和保護(hù)太多或太少的數(shù)據(jù)
標(biāo)準(zhǔn) C++ 庫(kù)提供了std::lock_guard類模板,它實(shí)現(xiàn) 了互斥鎖的RAII習(xí)慣用法。它在構(gòu)造時(shí)鎖定提供的互斥鎖并在銷毀時(shí)解鎖它,從而確保始終正確解鎖鎖定的互斥鎖。
#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é)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)停車管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)停車管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C語(yǔ)言實(shí)現(xiàn)學(xué)生宿舍信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)學(xué)生宿舍信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C++使用數(shù)組來(lái)實(shí)現(xiàn)哈夫曼樹
給定N個(gè)權(quán)值作為N個(gè)葉子結(jié)點(diǎn),構(gòu)造一棵二叉樹,若該樹的帶權(quán)路徑長(zhǎng)度達(dá)到最小,稱這樣的二叉樹為最優(yōu)二叉樹,也稱為哈夫曼樹(Huffman?Tree)。哈夫曼樹是帶權(quán)路徑長(zhǎng)度最短的樹,權(quán)值較大的結(jié)點(diǎn)離根較近2022-05-05
C語(yǔ)言設(shè)計(jì)圖書登記系統(tǒng)與停車場(chǎng)管理系統(tǒng)的實(shí)例分享
這篇文章主要介紹了C語(yǔ)言設(shè)計(jì)圖書登記系統(tǒng)與停車場(chǎng)管理系統(tǒng)的實(shí)例分享,重在以最簡(jiǎn)單的一些需求來(lái)展示管理系統(tǒng)的設(shè)計(jì)思路,需要的朋友可以參考下2016-06-06
C++實(shí)現(xiàn)Window環(huán)境聊天室功能
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)Window環(huán)境聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06

