日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【C++】多线程与并发【一】

發布時間:2023/11/27 生活经验 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++】多线程与并发【一】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • part 0:多線程簡介
      • part 1:多線程構造
        • 它用于構造線程對象。
        • 參量
      • part 2:多線程析構
        • 它破壞線程對象。
      • part 3:多線程operator=
        • 參量 Parameters
        • 返回值
    • Data races
      • part 4:joinable 它返回線程ive對象是否可連接,則返回true,否則返回false。 表示的是否可連接狀態.
      • part 5:多線程std :: thread :: get_id
        • Declaration
      • C++11
      • part 6:native_handle 返回底層實現定義的線程句柄
      • part 7:hardware_concurrency 返回實現支持的并發線程數
        • Description
        • Return Value
      • part 8:join 線程執行完成后返回
      • part 9:detach 容許線程從線程句柄獨立開來執行
        • Description
      • part 10:swap 交換二個 `thread` 對象
        • Description
        • Declaration
      • part 11:std::swap 特化 [std::swap](https://zh.cppreference.com/w/cpp/algorithm/swap) 算法
        • Description
        • Declaration
        • Parameters
        • 實例:
    • 小結:
        • **當線程不需要相互依賴,不會產生數據競爭,或不是流水的實現思路下,用detach();**
        • **當可能產生數據競爭,數據之間相互依賴,算法實現設計為流水的情況下,使用join()函數,使其他線程進入阻塞狀態。**

part 0:多線程簡介

Thread是一個指令序列,它可以在多線程環境中與其他這樣的序列同時執行,同時共享同一個地址空間。

Thread is a sequence of instructions that can be executed concurrently with other such sequences in multithreading environments, while sharing a same address spac.

Member typesDescription成員類型
idIt is a values of this type are returned by thread::get_id and this_thread::get_id to identify threads.It is a thread id.表示線程的id1
native_handle_typeIt is a member type and it presents in class thread if the library implementation supports it.實現定義It is a native handle type.2
Member functions成員函數
constructorIt is used to construct thread.構造新的 thread 對象3
destructorIt is used to destructor thread.析構 thread 對象,必須合并或分離底層線程4
operator=It is a move-assign thread.移動 thread 對象5
get_idIt is used to get thread id.返回線程的 *id6
joinableIt is used to check if joinable.檢查線程是否可合并,即潛在地運行于平行環境中7
joinIt is used to join thread.等待線程完成其執行8
detachIt is used to detach thread.容許線程從線程句柄獨立開來執行9
swapIt is used to swap threads.交換二個 thread 對象10
native_handleIt is used to get native handle.返回底層實現定義的線程句柄11
hardware_concurrencyIt is used to detect hardware concurrency.返回實現支持的并發線程數12
Non-member overload & description非成員函數
swapIt is used to swap threads.特化 std::swap 算法13

part 1:多線程構造

它用于構造線程對象。

It is used to constructs a thread object.

以下是std :: thread :: thread函數的聲明。

thread() noexcept;
template <class Fn, class... Args>
explicit thread (Fn&& fn, Args&&... args);
thread (const thread&) = delete;	
thread (thread&& x) noexcept;

參量

  • **fn-**它是函數的指針,成員的指針或任何可移動構造的函數對象。
  • **args …-**傳遞給fn調用的參數。
  • **x-**這是一個線程對象。
#include <thread> //頭文件
#include <iostream>
using namespace std;void fn1(void)
{cout << "fn1" << endl;
}void fn2(int a)
{cout << "fn2 " << a << endl;
}void fn3(int& a)
{cout << "fn3 " << a << endl;
}class cls
{
public:void fn1(int a){cout << "cls::fn1" << endl;}
};void test01() {std::thread t1(&fn1); //線程對象構造后,即開始執行//可被 joinable 的 thread 對象必須在他們銷毀之前被主線程 join 或者將其設置為 detachedt1.join(); //必須執行join,不然運行期錯誤std::thread t2(&fn2, 2); //傳入函數參數t2.join();int n = 2;std::thread t3(&fn3, std::ref(n)); //傳入引用參數t3.join();cls c;//線程入口為類成員函數std::thread t4(&cls::fn1, &c, 2);t4.join();
}
int main()
{test01();getchar();return 0;
}

cpp多線程并發 頭文件的使用,正則化實現

#include <iostream>
#include <thread>int main(void)
{std::thread x([]()->void {int i = 4;while (i--){std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << "*" << std::endl;}return;});std::thread y([]()->void {int i = 4;while (i--){std::this_thread::sleep_for(std::chrono::seconds(5));std::cout << "-" << std::endl;}return;});std::cout << std::thread::hardware_concurrency() << std::endl; //檢測計算機并發數std::cout << "x.hand " << x.native_handle() << std::endl;std::cout << "y.hand " << y.native_handle() << std::endl;//脫離主線程后不能直接獲取句柄,所以放輸出語句后面后面x.detach();y.detach();std::this_thread::sleep_for(std::chrono::seconds(30));//等待程序執行完成return 0;
}

part 2:多線程析構

它破壞線程對象。

It destroys the thread object. Following is the declaration for std::thread::~thread function.

~thread();

part 3:多線程operator=

以下是std :: thread :: operator =函數的聲明。

It is used to move-assign thread. Following is the declaration for std::thread::operator= function.

thread& operator= (thread&& rhs) noexcept;	
thread& operator= (const thread&) = delete;

參量 Parameters

rhs ? It is a othread object.

RHS -這是一個othread對象。

返回值

它返回* this

Data races

rhs和對象均被修改。

Both rhs and the object are modified.

part 4:joinable 它返回線程ive對象是否可連接,則返回true,否則返回false。 表示的是否可連接狀態.

It returns whether the thread object is joinable.

It returns true if the thread is joinable or else false.

#include <iostream>
#include <thread>void foo02() {std::this_thread::sleep_for(std::chrono::seconds(2));
}void test02() {//joinablestd::thread t2;//創建了線程對象std::cout << "before joneable: " << t2.joinable() << std::endl;t2 = std::thread(foo02);//joinable  //實例化std::thread對象時傳遞了“函數名/可調用對象”std::cout << "after joneable: " << t2.joinable() << std::endl;t2.join();//等待std::cout << "after joining,joinable: " << t2.joinable()<<std::endl;
}int main() {	test02();getchar();return 0;
}

part 5:多線程std :: thread :: get_id

Declaration

下面是std::thread::get_id函數的聲明。 Following is the declaration for std::thread::get_id function.

id get_id() const noexcept;

C++11

id get_id() const noexcept;

Return Value:It returns the thread id.

Exceptions:No-throw guarantee ? never throws exceptions.

Data races:he object is accessed.

#include <iostream>
#include <thread>
#include <chrono>void foo() {std::this_thread::sleep_for(std::chrono::seconds(1));
}int main() {std::thread sample(foo);std::thread::id sample_id = sample.get_id();std::thread sample2(foo);std::thread::id sample2_id = sample2.get_id();std::cout << "sample's id: " << sample_id << '\n';std::cout << "sample2's id: " << sample2_id << '\n';sample.join();sample2.join();
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-RgA6jWST-1609517496473)(C:\Users\guoqi\AppData\Roaming\Typora\typora-user-images\1609344040208.png)]

part 6:native_handle 返回底層實現定義的線程句柄

Declaration:Following is the declaration for std::thread::native_handle function.

native_handle_type native_handle();

Return Value:It returns a value of member type thread::native_handle_type.

part 7:hardware_concurrency 返回實現支持的并發線程數

Description

It returns the number of hardware thread contexts.

static unsigned hardware_concurrency() noexcept;

Return Value

It returns the number of hardware thread contexts.

part 8:join 線程執行完成后返回

It returns when the thread execution has completed.

void foo03() {std::this_thread::sleep_for(std::chrono::seconds(2));
}
void bar03() {std::this_thread::sleep_for(std::chrono::seconds(2));
}
void test03() {//join 線程執行完成后返回//It returns when the thread execution has completed.std::cout << " starting helping ...." << std::endl;std::thread helper3(foo02);std::cout << " starting another helping ...." << std::endl;std::thread helper3_2(bar03);std::cout << " waiting for helpers finish...." << std::endl;helper3.join();//線程執行完成后返回helper3_2.join();std::cout << "  done!" << std::endl;
}int main() {test03();getchar();return 0;
}

part 9:detach 容許線程從線程句柄獨立開來執行

Description

It returns when the thread execution has completed.

#include <iostream>
#include <chrono>
#include <thread>void independentThread() {std::cout << "Starting thread.\n";std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << "Exiting previous thread.\n";
}void threadCaller() {std::cout << "Starting thread caller.\n";std::thread t(independentThread);t.detach();std::this_thread::sleep_for(std::chrono::seconds(1));std::cout << "Exiting thread caller.\n";
}int main() {threadCaller();std::this_thread::sleep_for(std::chrono::seconds(5));
}

part 10:swap 交換二個 thread 對象

Description

It swaps the state of the object with that of x.

Declaration

Following is the declaration for std::thread::swap function.

void swap (thread& x) noexcept;

part 11:std::swap 特化 std::swap 算法

Description

It is used to exchanges the state of the thread objects x and y.

Declaration

Following is the declaration for std::thread::swap function.

void swap (thread& x, thread& y) noexcept;

Parameters

x,y ? It is a thread objects.

實例:

//thread1.cpp  創建線程,并觀察線程的并發執行與阻塞等待#include <iostream>
#include <thread>
#include <chrono>using namespace std;void thread_function(int n)
{std::thread::id this_id = std::this_thread::get_id();			//獲取線程IDfor(int i = 0; i < 5; i++){    cout << "Child function thread " << this_id<< " running : " << i+1 << endl;std::this_thread::sleep_for(std::chrono::seconds(n));   	//進程睡眠n秒}
}class Thread_functor
{
public:// functor行為類似函數,C++中的仿函數是通過在類中重載()運算符實現,使你可以像使用函數一樣來創建類的對象void operator()(int n){std::thread::id this_id = std::this_thread::get_id();for(int i = 0; i < 5; i++){cout << "Child functor thread " << this_id << " running: " << i+1 << endl;std::this_thread::sleep_for(std::chrono::seconds(n));   //進程睡眠n秒}}	
};int main()
{thread mythread1(thread_function, 1);      // 傳遞初始函數作為線程的參數if(mythread1.joinable()) //判斷是否可以成功使用join()或者detach(),返回true則可以,false則不可mythread1.join();                     // 使用join()函數阻塞主線程直至子線程執行完畢Thread_functor thread_functor;			 //函數對象實例化一個對象thread mythread2(thread_functor, 3);     // 傳遞初始函數作為線程的參數if(mythread2.joinable())mythread2.detach();  // 使用detach()函數讓子線程和主線程并行運行,主線程也不再等待子線程//lambda表達式格式:[capture list] (params list) mutable exception-> return type { function body }auto thread_lambda = [](int n){			std::thread::id this_id = std::this_thread::get_id();for(int i = 0; i < 5; i++){cout << "Child lambda thread " << this_id << " running: " << i+1 << endl;std::this_thread::sleep_for(std::chrono::seconds(n));   //進程睡眠n秒}       };thread mythread3(thread_lambda, 4);     // 傳遞初始函數作為線程的參數if(mythread3.joinable())mythread3.join();                     // 使用join()函數阻塞主線程直至子線程執行完畢std::thread::id this_id = std::this_thread::get_id();for(int i = 0; i < 5; i++){cout << "Main thread " << this_id << " running: " << i+1 << endl;std::this_thread::sleep_for(std::chrono::seconds(1));}getchar();return 0;
}

線程創建的參數是函數對象,函數對象不止是函數指針成員函數指針,同時還包括函數對象(仿函數)lambda表達式。上面的代碼分別用三種函數對象創建了三個線程**,其中第一個線程mythread1阻塞等待其執行完后繼續往下執行**,第二個線程mythread2不阻塞等待在后臺與后面的第三個線程mythread3并發執行,第三個線程繼續阻塞等待其完成后再繼續往下執行主線程任務。

為了便于觀察并發過程,對三個線程均用了睡眠延時this_thread::sleep_for(duration)函數,且延時時間作為參數傳遞給該函數。這里的參數是支持C++泛型模板的,STL標準容器類型(比如Array/Vector/Deque/List/Set/Map/String等)都可以作為參數傳遞,但這里的參數默認是以拷貝的方式傳遞參數的,當期望傳入一個引用時,要使用std::ref進行轉換,實例見part 1中實例。

如果想要線程mythread2獨立運行,修改如下

mythread2.detach(); ---》   mythread2.join();


線程mythread2和線程mythread3與主線程main 同步運行

mythread2.detach(); ---》   mythread2.join();
mythread3.join();   ---》   mythread3.detach();

小結:

當線程不需要相互依賴,不會產生數據競爭,或不是流水的實現思路下,用detach();

當可能產生數據競爭,數據之間相互依賴,算法實現設計為流水的情況下,使用join()函數,使其他線程進入阻塞狀態。

針對任何線程(包括主線程),< thread > 還聲明了一個命名空間std::this_thread,用以提高線程專屬的全局函數。函數聲明和效果見下表。 上面的代碼就是利用了std::this_thread提供的函數獲得當前線程的ID,讓當前線程睡眠一段時間(一般需要< chrono >頭文件提供duration或timepoint)的功能 。

參考資料:
https://zh.cppreference.com/w/cpp/thread/thread
https://www.tutorialspoint.com/cpp_standard_library
https://blog.csdn.net/m0_37621078/article/details/104909834

總結

以上是生活随笔為你收集整理的【C++】多线程与并发【一】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。