多線程編程的基本概念,C++標準庫中的多線程支持(std::thread,std::async),如何處理線程同步和并發問題。

多線程編程在現代計算機系統中非常重要,因為它能夠使程序同時執行多個操作,提高計算效率。以下是多線程編程的基本概念及如何在C++標準庫中使用std::threadstd::async進行多線程編程,同時處理線程同步和并發問題。

多線程編程的基本概念

  1. 線程(Thread):

    • 線程是一個輕量級的進程,是操作系統能夠獨立管理的基本單元。一個進程可以包含多個線程,這些線程共享進程的資源(如內存、文件句柄等)。
  2. 并發與并行(Concurrency vs. Parallelism):

    • 并發是指程序能夠在同一時間處理多個任務。具體而言,雖然任務可能并不是同時運行的,但它們在程序中的執行順序會交錯進行。
    • 并行是指程序在同一時刻實際執行多個任務。并行通常需要多核處理器,多個任務真正同時進行。
  3. 線程安全(Thread Safety):

    • 當多個線程訪問共享資源(如全局變量、文件等)時,如果沒有適當的同步機制,就可能出現數據競爭(Data Race)和死鎖(Deadlock)等問題。線程安全是指程序在多線程環境下運行時,能夠正確地處理并發訪問,不會出現錯誤。

C++ 標準庫中的多線程支持

C++11引入了豐富的多線程支持,主要包括std::threadstd::async等工具。以下是它們的基本用法:

1. std::thread

std::thread提供了一個簡單的接口來創建和管理線程。下面是一個基本的示例:

#include <iostream>
#include <thread>// 線程執行的函數
void print_hello() {std::cout << "Hello from thread!" << std::endl;
}int main() {// 創建線程并啟動std::thread t(print_hello);// 等待線程完成t.join();std::cout << "Hello from main!" << std::endl;return 0;
}

在這個示例中,std::thread t(print_hello); 創建并啟動了一個新線程來執行print_hello函數。t.join(); 用于等待線程t完成。

2. std::async

std::async是一個高層次的接口,用于啟動異步任務,并且它返回一個std::future對象,用于獲取異步任務的結果。下面是一個基本的示例:

#include <iostream>
#include <future>// 異步執行的函數
int compute_sum(int a, int b) {return a + b;
}int main() {// 使用 std::async 啟動異步任務std::future<int> result = std::async(std::launch::async, compute_sum, 10, 20);// 獲取異步任務的結果int sum = result.get();std::cout << "Sum is: " << sum << std::endl;return 0;
}

在這個示例中,std::async啟動了一個異步任務來計算兩個整數的和,并返回一個std::future對象result。通過調用result.get(),可以獲得異步任務的結果。

線程同步和并發問題的處理

為了保證線程安全,需要使用同步機制來管理對共享資源的訪問。C++標準庫提供了一些常用的同步原語:

  1. 互斥量(Mutex):

    • std::mutex:用于在多個線程之間保護共享資源,確保一次只有一個線程可以訪問資源。
    • std::lock_guard:用于簡化互斥量的使用,在一個作用域內自動鎖定和解鎖互斥量。
      #include <iostream>
      #include <thread>
      #include <mutex>std::mutex mtx; // 互斥量void print_number(int n) {std::lock_guard<std::mutex> lock(mtx);std::cout << "Number: " << n << std::endl;
      }int main() {std::thread t1(print_number, 1);std::thread t2(print_number, 2);t1.join();t2.join();return 0;
      }
      

?

2.條件變量(Condition Variable):

  • std::condition_variable:用于線程間的通信,使一個線程能夠等待另一個線程的某個條件滿足。
  • std::unique_lock:用于與條件變量一起使用,能夠更靈活地控制互斥量的鎖定和解鎖。

?

#include <iostream>
#include <thread>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void print_message() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return ready; }); // 等待條件滿足std::cout << "Thread is running!" << std::endl;
}int main() {std::thread t(print_message);{std::lock_guard<std::mutex> lock(mtx);ready = true; // 設置條件為 true}cv.notify_one(); // 通知等待的線程t.join();return 0;
}

3.原子操作(Atomic Operations):

  • std::atomic:提供對基本數據類型的原子操作,避免使用鎖的開銷。
    #include <iostream>
    #include <thread>
    #include <atomic>std::atomic<int> counter(0);void increment() {for (int i = 0; i < 1000; ++i) {++counter;}
    }int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Counter: " << counter.load() << std::endl;return 0;
    }
    

    在這個示例中,std::atomic<int> 保證了對 counter 的操作是線程安全的,不需要使用互斥量來保護它。

    通過正確地使用這些工具和同步機制,可以有效地管理多線程程序中的并發問題,提高程序的性能和可靠性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/40338.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/40338.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/40338.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

K8S學習教程(二):在 PetaExpress KubeSphere容器平臺部署高可用 Redis 集群

前言 Redis 是在開發過程中經常用到的緩存中間件&#xff0c;為了考慮在生產環境中穩定性和高可用&#xff0c;Redis通常采用集群模式的部署方式。 在制定Redis集群的部署策略時&#xff0c;常規部署在虛擬機上的方式配置繁瑣并且需要手動重啟節點&#xff0c;相較之下&#…

十款絢麗的前端 CSS 菜單導航動畫

CSS漢堡菜單是一種非常流行的PC端和移動端web菜單風格&#xff0c;特別是移動端&#xff0c;這種風格的菜單應用更為廣泛。這款菜單便非常適合在手機App上使用&#xff0c;它的特點是當頂部菜單彈出時&#xff0c;頁面內容將會配合菜單出現適當的聯動&#xff0c;讓整個頁面變得…

關于linux捕捉鼠標事件的方法

網上找了很多方法&#xff0c;都比較雜亂。這篇文章專注于讀取鼠標的動作&#xff1a;左鍵、右鍵、中鍵、滾輪。 linux的設備都以文件形式存放&#xff0c;要讀取鼠標&#xff0c;有兩種方法&#xff0c;一種是通過/dev/input/mice&#xff0c;一種是通過/dev/input/eventx (x…

探索線程安全:HashMap 的四種使用技巧

這篇文章&#xff0c;我們聊聊線程安全使用 HashMap 的四種技巧。 1 方法內部&#xff1a;每個線程使用單獨的 HashMap 如下圖&#xff0c;tomcat 接收到到請求后&#xff0c;依次調用控制器 Controller、服務層 Service 、數據庫訪問層的相關方法。 每次訪問服務層方法 serv…

vue H5頁面video 視頻流自動播放, 解決ios不能自動播放問題

視頻組件 <videostyle"width: 100%; height: 100%;object-fit: fill"class"player"refplayer_big_boxcontrolspreloadautoplay //自動播放muted //是否靜音playsinline"true"x5-playsinline""webkit-playsinline"tru…

[Linux安全運維] Linux用戶以及權限管理

Linux用戶以及權限管理 Linux用戶和組 用戶信息文件pasawd /etc/passwd文件用于存儲用戶的信息 :用于分割不同的字段信息 字段示例&#xff08;第一行&#xff09;含義說明1root用戶名2x密碼占位符x代表用戶有密碼存儲在shadow文件中無內容代表用戶登錄系統不需要密碼30UID…

梧桐數據庫:存算分離和存算一體架構的分布式數據庫技術分析

摘要&#xff1a; 隨著數據量的不斷增長和對數據處理性能的要求越來越高&#xff0c;分布式數據庫技術成為了數據存儲和處理的重要解決方案。存算分離和存算一體是兩種常見的分布式數據庫架構&#xff0c;它們在數據存儲和計算方面有著不同的特點和優勢。本文將對存算分離和存算…

Spring源碼(一) 如何閱讀 Spring 源碼

學習 Spring 的源碼&#xff0c;也可以通過 SpringBoot 搭環境。 不管是什么源碼&#xff0c;最好寫個 demo&#xff0c;跑起來&#xff0c;然后從常用的類和方法入手&#xff0c;跟蹤調試。 配置對象 新建一個 SpringBoot 的項目&#xff0c; 詳情見&#xff1a; https://b…

FreeRTOS 中 vListInsertEnd 函數詳解

在 FreeRTOS 中&#xff0c;vListInsertEnd 函數用于將新項插入到指定列表的尾部&#xff08;但實際行為是插入到一個特定的索引位置之前&#xff09;。FreeRTOS 使用雙向鏈表&#xff08;doubly linked list&#xff09;來管理任務和其他系統對象&#xff0c;這樣可以高效地插…

前端三件套開發模版——產品介紹頁面

今天有空&#xff0c;使用前端三件套html、css、js制作了一個非常簡單的產品制作頁面&#xff0c;與大家分享&#xff0c;希望可以滿足大家應急的需求。本頁面可以對產品進行“搶購”、對產品進行介紹&#xff0c;同時可以安排一張產品的高清大圖&#xff0c;我也加入了頁面的背…

JAVA實現二分查找,斐波那契數列,深度優先搜索詳情教程【包含代碼】

本人詳解 作者:王文峰,參加過 CSDN 2020年度博客之星,《Java王大師王天師》 公眾號:JAVA開發王大師,專注于天道酬勤的 Java 開發問題中國國學、傳統文化和代碼愛好者的程序人生,期待你的關注和支持!本人外號:神秘小峯 山峯 轉載說明:務必注明來源(注明:作者:王文峰…

react+ts+antd項目搭建

前言&#xff1a; 基于ts語言創建react項目&#xff0c;node版本是v16.14.2 一、 腳手架創建項目 全局安裝 npm install -g creacte-react-app創建項目file-management&#xff0c;ts需要添加–template typescript npx create-react-app file-management --template typesc…

Ubuntu查看opencv版本c++

?命令行中直接輸入&#xff1a; pkg-config --modversion opencv?命令行中直接輸入&#xff1a; pkg-config --modversion opencv4注解&#xff1a;附上在markdown中打勾&#xff0c;對號和打叉。使用時將&和#之間的空格去掉&#xff0c;這里只是為了不讓CSDN自動轉換才…

Ubuntu20.04 c++程序 涉及opencv問題記錄

頭文件更改 默認的頭文件引用是 #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp>但是在ubuntu20中/usr/include中默認的是opencv4&#xff0c;他文件夾里面才是opencv2&#xff0c;需要…

vue3單個頁面進行防抖節流

防抖 <template><button id"submitButton" ref"submitButton">GET</button> </template><script lang"ts" setup> import { ref, onMounted } from vue;// 防抖函數 function debounce(func: () > void, dela…

【mybatis】mybatis-plus中Wrapper(查詢條件構造器)簡介_常用方法

1、簡介 MyBatis-Plus 是一個 MyBatis 的增強工具&#xff0c;在 MyBatis 的基礎上只做增強不做改變&#xff0c;為簡化開發、提高效率而生。MyBatis-Plus 提供了強大的條件構造器&#xff08;Wrapper&#xff09;&#xff0c;用于構建復雜的 SQL 查詢條件&#xff0c;使得我們…

溝通方法和技巧

0 Preface/Foreword 1 溝通對象 溝通維度&#xff1a; upward&#xff0c;向上溝通&#xff0c;直接上級downward&#xff0c;向下溝通&#xff0c;直接下級horizontal&#xff0c;橫向溝通&#xff0c;同部門/跨部門同事 2 溝通方式&#xff08;5W2H&#xff09; 對于開會和…

小白嘗試某程機票信息爬取

實訓課需要機票數據集&#xff0c;網上沒有&#xff0c;所以我選擇爬取數據 此過程可謂經歷的九九八十一難&#xff0c;也參考了不少大佬的文章&#xff0c;在此特別記錄一下 彎路不多說&#xff0c;我直接講成功的方法 找到請求url 通過控制臺&#xff0c;最后確認下面的 …

在WordPress中獲取10天之內的文章更新數

要在WordPress中獲取10天之內的文章更新數&#xff0c;您可以使用以下代碼片段。這段代碼將顯示在過去10天內更新的文章數量。 <?php // 獲取當前時間戳 $now time();// 計算10天前的時間戳 $ten_days_ago $now - (10 * 24 * 60 * 60);// 設置查詢參數 $args array(pos…

【Spring Boot AOP中切入表達式格式介紹】

文章目錄 一、切入表達式簡介二、切入表達式的語法1. 方法匹配符示例&#xff1a; 2. 類型匹配符示例&#xff1a; 一、切入表達式簡介 切入表達式&#xff08;Pointcut Expression&#xff09;是AOP中定義切入點&#xff08;Pointcut&#xff09;的一種方式。它定義了在哪些連…