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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++11 多线程 基础

發布時間:2023/12/18 c/c++ 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++11 多线程 基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C++11開始支持多線程編程,之前多線程編程都需要系統的支持,在不同的系統下創建線程需要不同的API如pthread_create(),Createthread(),beginthread()等,使用起來都比較復雜,C++11提供了新頭文件<thread>、<mutex>、<atomic>、<future>等用于支持多線程。

使用C++11開啟一個線程是比較簡單的,下面來看一個簡單的例子:

#include <thread>

#include <iostream>

?

void hello()

{

??? std::cout << "Hello from thread " << std::endl;

}

?

int main()

{

??? std::thread t1(hello);

??? t1.join();

std::cout<<"Main Thread"<<std::endl;

??? return 0;

}

運行結果:

說明,通過thread 類直接申明一個線程t1,參數是這個線程執行的回調函數的地址,通過jion()方法阻塞主線程,直到t1線程執行結束為止。

?

???????? C++11支持Lambda表達式,因此一個新線程的回調函數也可以是有一個Lambda表達式的形式,但是注意如果使用Lambda表達式最好不要使用引用的方式,應該使用值傳遞的方式來訪問數據,在多線程中使用引用容易造成混亂。下面這個例子稍微復雜,創建了多個子線程,并使用了get_id()方法來獲取當前線程的id。

#include <thread>

#include <iostream>

#include <vector>

?

int main()

{

??? std::vector<std::thread> threads;

?

??? for(int i = 0; i < 5; ++i){

??????? threads.push_back(std::thread([](){

??????????? std::cout << "Hello from lamda thread " << std::this_thread::get_id() << std::endl;

??????? }));

??? }

?

??? for(auto& thread : threads){

??????? thread.join();

??? }

?

??? std::cout<<"Main Thread"<<"\t"<<std::this_thread::get_id()<<std::endl;

??? return 0;

}

運行結果:

上述代碼中,使用vector來存放每個線程,線程的回調函數通過Lambda表達式產生,注意后面join的使用方式。

?

可以通過sleep_for來使線程睡眠一定的時間:

#include <thread>

#include <iostream>

#include <mutex>

using namespace std;

?

int main()

{

??? std::mutex m;

??? thread t1([&m]()

??? {

??????? std::this_thread::sleep_for (chrono::seconds(10));?

??????? for(int i=0;i<10;i++)?

??????? ?{?????

??????????? m.lock();?

??????????????? cout <<? "In t1 ThreadID : " << std::this_thread::get_id() << ":" << i << endl;?????????

??????????? m.unlock ();?

??????? }?

??? } );

?

??? thread t2([&m]()?

??? {??????????

??? ??? std::this_thread::sleep_for (chrono::seconds(1));?

??? ??? for(int i=0;i<10;i++)?

??? ??? {?????????

??? ??????? m.lock ();?

??? ??????????? cout <<? "In t2 ThreadID : " << std::this_thread::get_id() << ":" << i << endl;?????????

??? ??????? m.unlock();?

??? ??? }?

??? } );?

??? t1.join();?????

??? t2.join();?????

?

??? cout<<"Main Thread"<<endl;

?

??? return 0;

}

運行結果:

可以看出,由于線程t1睡眠的時間較長,t2先執行了。

延時有這幾種類型:nanoseconds、microseconds、milliseconds、seconds、minutes、hours。

在使用多線程的程序中操作共享數據的時候一定要小心,由于線程的亂序執行,可能會得到意想不到的結果。通過下面的程序來看:

#include <thread>

#include <iostream>

#include <vector>

#include <mutex>

?

struct Counter {

??? std::mutex mutex;

??? int value;

?

??? Counter() : value(0) {}

?

??? void increment(){

?????? // mutex.lock();??????????????? 【1】表示沒有使用鎖

??????? ++value;

?????? // mutex.unlock();????????????? 【1】

??? }

?

??? void decrement(){

??????? mutex.lock();

??????? --value;

??????? mutex.unlock();

??? }

};

?

int main(){

??? Counter counter;

?

??? std::vector<std::thread> threads;

?

??? for(int i = 0; i < 5; ++i){

??????? threads.push_back(std::thread([&](){

??????????? for(int i = 0; i < 10000; ++i){

??????????????? counter.increment();

??????????? }

??????? }));

??? }

?

??? for(auto& thread : threads){

??????? thread.join();

??? }

?

??? std::cout << counter.value << std::endl;

?

??? return 0;

}

運行結果:

【1】

運行結果:(使用了鎖)

說明:由于創建線程是使用lambda表達式,并使用引用的方式訪問counter這個變量,當沒有使用lock來保護的時候(情況【1】),執行的結果可能不像預期的5000(程序的意思是每個線程使counter中的value自加1000次,5個線程運行結束的時候應該是5000),當沒有使用鎖的時候自加的操作可能被其他線程打斷,因此結果可能會小于5000。

?

?

make it simple, make it happen

轉載于:https://www.cnblogs.com/lvdongjie/p/4487723.html

總結

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

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