C++并发编程实战
目錄
- 并發
- 為什么要使用并發?
- 線程管理
- 等待線程完成
- 后臺運行程序
- 線程間共享數據
- 避免惡性條件競爭
- 使用互斥量保護共享數據
- 死鎖
- 二級目錄
- 三級目錄
并發
- 最簡單和最基本的并發,是指兩個或更多獨立的活動同時發生。
- 在計算機領域的并發是指在單個系統里同時執行多個獨立的任務,而非順序的進行一些活動。
并發的途徑:
(1)多進程并發:是將應用程序分為多個獨立的進程,它們在同一時刻運行,就像同時進行網頁瀏覽和文字處理一樣。
(2)多線程并發:在單個進程中運行多個線程:
多線程并發特點:
(a).線程很像輕量級的進程,每個線程相互獨立運行,且線程可以在不同的指令序列中運行。
(b).進程中的所有線程都共享地址空間(難建立,因為同一數據的內存地址在不同的進程中是不同的)
為什么要使用并發?
主要原因:關注點分離(SOC)和性能兩種方式利用并發提高性能:
- 將一個單個任務分成幾部分,且各自并行運行,從而降低總運行時間(任務并行)
- 在數據方面,每個線程在不同的數據部分上執行相同的操作(數據并行)
當收益比不上成本,不使用并發!!!
線程管理
線程管理
主要內容:
● 啟動新線程
● 等待線程與分離線程
● 線程唯一標識
等待線程完成
- join()是簡單粗暴的等待線程完成或不等待;調用join()的行為,還清理了線程相關的存儲部分,這樣std::thread對象將不再與已經完成的線程有任何關聯。這意味著,只能對一個線程使用一次join();一旦已經使用過join()。std::thread對象就不能再次加入了,當對其使用joinable()時,將返回false。
后臺運行程序
- 使用detach()會讓線程在后臺運行,這就意味著主線程不能與之產生直接交互。
- 通常稱分離線程稱為守護線程,UNIX中守護線程是指,沒有任何顯式的用戶接口,并在后臺運行的線程。
線程間共享數據
本章主要內容:
● 共享數據帶來的問題
● 使用互斥量保護數據
● 數據保護的替代方案
問題:條件競爭
避免惡性條件競爭
● 一是對數據結構和不變量的設計進行修改,修改完的結構必須能完成一系列不可分割的變化,也就是保證每個不變量保持穩定的狀態,這就是無所謂的無鎖編程。
● 處理條件競爭,使用事務的方式去處理數據結構的更新
保護數據共享結構的最基本方式,是使用C++標準庫提供的互斥量。
使用互斥量保護共享數據
- 當訪問共享數據前,將數據鎖住,在訪問結束后,再將數據解鎖。
- C++中常用std::mutex創建互斥量,lock()對互斥量上鎖,unlock()進行解鎖
- 進階:C++標準庫為互斥量提供了一個RAII(資源獲取即初始化)語法的模板類std::lock_guard,,在構造時就能提供已鎖的互斥量,并在析構的時候進行解鎖,來保證一個已鎖互斥量被正確解鎖。
死鎖
C++標準庫中std::lock 可以一次性鎖住多個(兩個以上)的互斥量,并且沒有副作用(死鎖風險)
二級目錄
三級目錄
總結
- 上一篇: MySQL中的悲观锁和乐观锁
- 下一篇: 人工智能工程师都需要掌握哪些技能