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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C11 多线程初学1

發布時間:2023/12/20 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C11 多线程初学1 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C++ 11 多線程編程

  • 1、線程的創建和使用
    • 1.1 創建線程
    • 1.2 線程的使用
  • 2.實現線程同步
      • 2.1互斥鎖
      • 2.2 條件變量
  • 3.例
    • 1:兩線程交替打印奇偶數

1、線程的創建和使用

引入線程庫<thread>,其提供了thread類,創建一個線程即實例化一個該類的對象,以此進行線程的創建和使用。

#include<thread> using namespce std;

1.1 創建線程

一個線程可以用一個 thread 類的對象來表示,thread類中重載了構造函數和移動拷貝構造

#include<iostream> #include<thread>using namespace std;void funa() {cout << "thread_funa()" << endl; } int main() {//創建線程——構造函數thread a(funa);cout << a.get_id() << endl;//移動拷貝構造thread b(std::move(a));cout << b.get_id() << endl;b.join();//移動拷貝構造進行資源的交換,所有要注釋掉//a.join();cout << "main end" << endl;}

注意: thread類無拷貝構造函數、無賦值運算符,即不能直接用一個事先定義好的thread對象拷貝構造另一個thread對象,也不能不能進行賦值操作。但可以將臨時的thread對象賦值給另一個thread即移動拷貝構造,也可以移動賦值。

1.2 線程的使用

thread 提供的函數: 線程支持庫
thread類常用的成員函數:

成員函數含義
get_id()獲取當前thread對象的線程id
joinable()判斷當前線程是否活躍(是:true;否:false)即是否支持調用 join()
join()阻塞當前thread 對象所在的線程,直至thread 對象表示的線程執行完畢
detach()將當前線程從調用該函數的線程中分離出去,他們彼此獨立運行
swap()交換兩個線程的狀態

注意:每個thread 對象在調用析構銷毀前,要么調用 join() 函數令主線程等待子線程執行完畢,要么調用detach() 函數將子線程和主線程分離,二者必選一,否則存在以下問題:

  • 線程占用的資源無法全部釋放,造成內存泄露
  • 當主線程執行完畢而子線程未完時,程序執行引發異常。

在this_thread 命名空間的部分函數:

函數含義
get_id()獲得當前線程的 ID
yield()阻塞當前線程讓出cpu,直至條件成熟
sleep_for()阻塞當前線程指定的時間
sleep_until()阻塞當前線程,直至某個時間點為止

例:

//休眠1000毫秒,1s this_thread::sleep_for(chrono::milliseconds(1000));

2.實現線程同步

2.1互斥鎖

互斥鎖用 mutex 類(位于std命名空間中)的對象表示,定義在頭文件<mutex>頭文件中。
成員函數:lock()——加鎖; unlock()——解鎖
例:對臨界資源變量n的訪問

#include<mutex> using namespcase std; mutex m; //實例化mutex對象m void Show_n() {m.lock();cout << n << endl;m.unlock(); }

實現嚴格基于作用域的互斥體所有權包裝器:lock_fuard
原理:創建 lock_guard 對象時,它試圖接收給定互斥的所有權。控制離開創建 lock_guard 對象的作用域時,銷毀 lock_guard 并釋放互斥。即,創建即加鎖,作用域結束自動解鎖。

#include<mutex> using namespcase std; mutex m; //實例化mutex對象m void Show_n() {lock_guard<mutex> g1(m);cout << n << endl; } //作用域結束,析構g1,m解鎖

lock_gurad傳入兩個參數,第二個為adopt_lock標識時,表示該互斥量之前必須已經lock,才能使用此參數,故需要提前手動鎖定。

#include<mutex> using namespcase std; mutex m; //實例化mutex對象m void Show_n() {m.lock(); //手動鎖定lock_guard<mutex> g1(m, adopt_lock);cout << n << endl; } //作用域結束,析構g1,m解鎖

實現可移動的互斥體所有權包裝器:unique_lock
與lock_guard類似,用法更豐富。

成員函數含義
lock()鎖定
try_lock()嘗試鎖定,若不能,先去執行其他代碼并返回false;可以,進行加鎖并返回true
unlock()解鎖

unique_lock與lock_guard

unique_locklock_guard
手動lock、unlock支持不支持
參數支持 adopt_lock/try_to_lock/defer_lock支持 adopt_lock

try_to_lock: 嘗試用mutx的lock()去鎖定這個mutex,但如果沒有鎖定成功,會立即返回,不會阻塞在那里
defer_lock: 這個參數表示暫時先不lock,之后手動去lock,但是使用之前也是不允許去lock。

2.2 條件變量

C11提供的兩種表示條件變量的類:
都定義在<condition_variable>頭文件中,常與互斥鎖搭配使用,避免線程間搶奪資源。

  • condition_variable
    該類表示的條件變量只能和unique_lock類表示的互斥鎖搭配使用;
  • condition_variable_any
    該類表示的條件變量可以與任意類型的互斥鎖搭配使用(如:遞歸互斥鎖、定時互斥鎖等)

條件變量常用的成員函數

成員函數功能
wait()阻塞當前線程,等待條件成立
wait_for()阻塞當前線程的過程中,該函數會自動調用unlock()解鎖,令其他線程使用公共資源。當條件成立或超過指定的等待時間,該函數自動調用lock()加鎖,同時令線程繼續執行
wait_until()與wait_for() 類似,區別是其可以設定一個具體的時間點,當條件成立或等待時間超過了指定的時間點,函數自動加鎖,線程執行
notify_one()喚醒一個等待的線程
notify_all()喚醒所有等待線程

關于wait() :
調用wait()1先獲得mutex,2線程被阻塞,當wait陷入休眠是會自動釋放mutex。直到另外某個線程調用 notify_one或notify_all喚醒了當前線程。當線程被喚醒時,此時線程是已經自動占有了mutex。

3.例

1:兩線程交替打印奇偶數

#include<iostream> #include<thread> #include<mutex> using namespace std; std::mutex data_mutex; std::condition_variable data_var; bool tag = true; // odd : 1 // even: 2 // odd : 3 // even : 4void printodd() // 打印奇數 {std::unique_lock<std::mutex> ulock(data_mutex);for (int odd = 1; odd <= 100; odd += 2){while (!tag){data_var.wait(ulock);}cout << "odd: " << odd << endl;tag = false;data_var.notify_all();} } void printeven() //打印偶數 {std::unique_lock<std::mutex> ulock(data_mutex);for (int even = 2; even <= 100; even += 2){ while (tag){data_var.wait(ulock);// 1 2 }cout << "even: " << even << endl;tag = true;data_var.notify_all();} }int main() {thread thodd(printodd);thread theven(printeven);thodd.join();theven.join();return 0; }

參考文獻:
C++多線程unique_lock詳解

總結

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

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