【學習筆記】鎖+死鎖+gdb調試死鎖

【學習筆記】鎖+死鎖+gdb調試死鎖

一、互斥鎖(std::mutex)

最基本的鎖類型,提供排他性訪問,同一時間僅允許一個線程持有鎖。

#include <iostream>
#include <mutex>
#include <thread>std::mutex mtx;  // 全局互斥鎖
int shared_data = 0;  // 共享資源void increment() {for (int i = 0; i < 100000; ++i) {std::lock_guard<std::mutex> lock(mtx);  // 自動加鎖++shared_data;  // 臨界區}  // 作用域結束,自動解鎖
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Final value: " << shared_data << std::endl;  // 輸出 200000return 0;
}

二、讀寫鎖(std::shared_mutex)

多讀單寫鎖,允許多個線程同時讀,但寫時獨占。適用于讀多寫少的場景。

#include <shared_mutex>  // C++17 及以上
#include <thread>
#include <vector>
#include <iostream>std::shared_mutex rw_mutex;
int shared_data = 0;// 讀操作(允許多線程并發)
void reader(int id) {for (int i = 0; i < 1000; ++i) {std::shared_lock<std::shared_mutex> lock(rw_mutex);  // 共享鎖(讀鎖)std::cout << "Reader " << id << ": " << shared_data << std::endl;}
}// 寫操作(獨占)
void writer() {for (int i = 0; i < 10; ++i) {std::unique_lock<std::shared_mutex> lock(rw_mutex);  // 獨占鎖(寫鎖)++shared_data;std::cout << "Writer updated: " << shared_data << std::endl;}
}int main() {std::vector<std::thread> readers;for (int i = 0; i < 5; ++i) {readers.emplace_back(reader, i);}std::thread w(writer);for (auto& t : readers) t.join();w.join();return 0;
}

std::shared_lock:用于讀操作,允許多個線程同時持有。

std::unique_lock:用于寫操作,獨占資源,同一時間僅允許一個線程持有。

三、高級鎖管理(std::unique_lock)

std::unique_lock 是一種比 std::lock_guard (自動加鎖)更靈活的鎖管理工具,主要用于需要手動控制鎖的生命周期的場景。

比如說想在某一處執行的地方,某一個變量的賦值之前加鎖,賦值完畢之后解鎖,比較靈活,但是需要注意解鎖。

#include <mutex>
#include <thread>std::mutex mtx;void worker() {std::unique_lock<std::mutex> lock(mtx, std::defer_lock);  // 構造時不加鎖// 執行無需鎖的操作...lock.lock();  // 手動加鎖// 臨界區lock.unlock();  // 手動解鎖// 執行其他無需鎖的操作...
}

std::unique_lock 在析構時會自動解鎖,因此忘記手動解鎖不會導致死鎖,但可能導致鎖持有時間過長,降低并發性能。

四、死鎖

https://www.51cto.com/article/623760.html

1、死鎖條件

死鎖的四個條件:

? ● 不可搶占(no preemption):系統資源不能被強制從一個進程(線程)中退出,已經獲得的資源在未使用完之前不能被搶占。

? ● 占有并等待(hold and wait):一個進程(線程)因請求資源阻塞時,對已獲得的資源保持不放。

? ● 互斥(mutual exclusion):資源只能同時分配給一個進程(線程),無法多個進程(線程)共享。

? ● 循環等待(circular waiting):一系列進程(線程)互相持有其他進程(線程)所需要的資源。

只有同時滿足以上四個條件,才會產生死鎖,想要消除死鎖只需要破壞其中任意一個條件即可。

using std::cout; std::mutex mutex1; 
std::mutex mutex2; 
std::mutex mutex3; void FuncA() { std::lock_guard<std::mutex> guard1(mutex1);  // 獲取mutex1std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒std::lock_guard<std::mutex> guard2(mutex2);  // 獲取mutex2(如果已被B持有,則阻塞)std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒
} void FuncB() { std::lock_guard<std::mutex> guard2(mutex2);  // 獲取mutex2std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒std::lock_guard<std::mutex> guard3(mutex3);  // 獲取mutex3(如果已被C持有,則阻塞)std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒
} void FuncC() { std::lock_guard<std::mutex> guard3(mutex3);  // 獲取mutex3std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒std::lock_guard<std::mutex> guard1(mutex1);  // 獲取mutex1(如果已被A持有,則阻塞)std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒
} int main() { std::thread A(FuncA); std::thread B(FuncB); std::thread C(FuncC); std::this_thread::sleep_for(std::chrono::seconds(5)); // 嘗試回收子線程if (A.joinable()) A.join(); if (B.joinable()) B.join(); if (C.joinable()) C.join(); cout << "hello\n";  // 永遠不會執行   return 0; 
} 

2、gdb調試死鎖

直接gdb+可執行程序,應該會什么都不打印,一直鼠標跳動。

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

線程 1 (LWP 3097)

  • 角色:主線程(從main函數啟動的線程)。
  • 狀態:阻塞在futex系統調用,等待某個條件(可能是等待子線程結束)。
  • 關鍵點expected=3100表明它在等待線程 ID 為 3100 的子線程(即 LWP 3100)。

線程 2 (LWP 3100)

  • 角色:執行FuncA()的線程(根據鎖地址匹配)。
  • 狀態:阻塞在mutex2(地址0x55555555a1a0)上。
  • 關鍵點expected=2表示它期望鎖的狀態為 2(可能是 “已鎖定”),但當前鎖被其他線程持有。

線程 3 (LWP 3101)

  • 角色:執行FuncB()的線程。
  • 狀態:阻塞在mutex3(地址0x55555555a1e0)上。

線程 4 (LWP 3102)

  • 角色:執行FuncC()的線程。

  • 狀態:阻塞在mutex1(地址0x55555555a160)上。

  • 等待的鎖:線程 2 在等待mutex2,線程 3 在等待mutex3,線程 4 在等待mutex1

  • 已持有的鎖:需結合源代碼邏輯推斷(例如線程 2 已持有mutex1,因為它在等待mutex2之前獲取了mutex1)。

死鎖原因分析:

結合你的原始代碼:

  1. 線程 2(FuncA) 已持有mutex1,正在等待mutex2
  2. 線程 3(FuncB) 已持有mutex2,正在等待mutex3
  3. 線程 4(FuncC) 已持有mutex3,正在等待mutex1

形成循環依賴鏈:線程 2 → 線程 3 → 線程 4 → 線程 2,導致死鎖。

在這里插入圖片描述

死鎖原因分析:

結合你的原始代碼:

  1. 線程 2(FuncA) 已持有mutex1,正在等待mutex2
  2. 線程 3(FuncB) 已持有mutex2,正在等待mutex3
  3. 線程 4(FuncC) 已持有mutex3,正在等待mutex1

形成循環依賴鏈:線程 2 → 線程 3 → 線程 4 → 線程 2,導致死鎖。

(gdb) thread apply all bt 也可以運行以下命令查看所有線程的堆棧

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

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

相關文章

Flutter中將bytes轉換成XFile對象上傳

在Flutter中將字節數據(bytes)轉換為XFile對象并上傳可以通過以下步驟實現&#xff1a; 1.字節數據轉臨時文件 首先需要將字節數據寫入臨時文件&#xff0c;可以使用dart的File類實現&#xff1a; final tempDir await getTemporaryDirectory(); final file File(${tempDi…

餅圖:數據可視化的“切蛋糕”藝術

餅圖&#xff0c;作為數據可視化家族中最經典、最易識別的成員之一&#xff0c;其核心功能如同其名——像切分蛋糕一樣&#xff0c;直觀展示一個整體&#xff08;100%&#xff09;被劃分為若干組成部分的比例關系。 往期文章推薦: 20.用Mermaid代碼畫ER圖&#xff1a;AI時代的…

Flutter - 原生交互 - 相機Camera - 曝光,縮放,錄制視頻

曝光 Flutter上CupertinoSlider組件的樣式是iOS上的Slider,使用該組件控制曝光量, Camera插件提供的API是CameraController的 Future<double> setExposureOffset(double offset) async {... }最后調用iOS端的系統方法控制曝光值 - (void)setExposureTargetBias:(floa…

Python中布爾值在函數中的巧妙運用

在 Python 中&#xff0c;布爾值&#xff08;True 和 False&#xff09;不僅可以用于簡單的條件判斷&#xff0c;還可以在函數中發揮強大的作用。通過合理使用布爾值&#xff0c;你可以使函數更加靈活、高效且易于理解。今天&#xff0c;就讓我們一起深入探討如何在函數中巧妙運…

解決sql查詢中in查詢項過多時很慢的問題

最近遇到查詢一張大數據量表時&#xff0c;需要對一個字段做in查詢&#xff0c;in中的元素數量可能達到幾千個&#xff0c;即使對這個字段加上索引&#xff0c;速度也慢到無法接受 示例表結構如下&#xff1a; 表中有幾十萬的數據&#xff0c;且example_id和data_id字段加了聯…

Spring---Spring MVC 執行流程

SpringMVC執行流程分為兩個&#xff1a;前后端分離與視圖階段&#xff08;不分離&#xff09; 視圖階段&#xff08;JSP/Thymeleaf/Freemarker&#xff09; SpringMVC 前后端分離階段 SpringMVC中重要組建有哪些&#xff1f; 前端控制器&#xff08;DispatcherServlet&#x…

Llama 4模型卡片及提示詞模板

Llama 4模型卡片及提示詞模板 Llama 4 模型卡及提示格式介紹 Llama 4 模型概述 Llama 4 是一系列預訓練和指令微調的混合專家(Mixture-of-Experts, MoE)大語言模型,包含兩種規模:Llama 4 Scout和Llama 4 Maverick。該模型針對多模態理解、多語言任務、編碼、工具調用及智…

使用Advanced Installer軟件將winform程序打包成exe安裝文件

使用Advanced Installer軟件將winform程序打包成exe安裝文件_c#程序打包軟件-CSDN博客 軟件的下載連接 https://download.csdn.net/download/qq_20222919/87780646

NDS 中文游戲全集下載 任天堂NDS簡介NDS支持GBA游戲

這是一份關于任天堂NDS游戲及其平臺的簡介&#xff1a; 游戲全集打包下載 https://pan.quark.cn/s/8805da9a09c4 NDS 是什么&#xff1f; 全稱&#xff1a; Nintendo DS (NDS)類型&#xff1a; 由任天堂開發和發行的掌上游戲機。世代&#xff1a; 第七世代游戲機 (與PSP、Wii…

Kamailio rtpengine_subscribe_request

master 版本的 rtpengine 新增了函數 rtpengine_subscribe_request 應該是 siprec 增加的 改天做下測試 參考鏈接&#xff1a; https://lists.kamailio.org/mailman3/hyperkitty/list/sr-userslists.kamailio.org/thread/Q7YJDVBHZX4BIWG23VRVRYW7N5SAAUOR/ https://kamai…

Java八股文——計算機網絡「網絡模型篇」

什么是OSI七層模型&#xff1f; 面試官您好&#xff0c;OSI&#xff08;Open Systems Interconnection&#xff09;七層模型&#xff0c;是由國際標準化組織&#xff08;ISO&#xff09;提出的一個網絡互聯的開放式參考模型。 它是一個理論上的、概念性的框架&#xff0c;其核…

國產服務器【銀河麒麟v10】【CPU鯤鵬920】部署Nacos

目錄 準備工作開始安裝1. 下載nacos2. 啟動3. 檢查 結束 準備工作 環境要求&#xff1a;Linux虛擬機nacos2.3.2 安裝包 開始安裝 1. 下載nacos 方式1 wget https://github.com/alibaba/nacos/releases/download/2.3.2/nacos-server-2.3.2.tar.gz方式2 去官網自行下載所需版…

一款強大的音視頻處理工具--FFmpeg-2--常用音頻處理示例

1、查看音頻文件詳細信息 opus&#xff0c;wav&#xff0c;pcm等音頻格式都適用。 ffprobe -i 1.opus說明&#xff1a; Input 0, ogg, from ‘1.opus’: Input 0&#xff1a;表示這是第一個輸入文件。ogg&#xff1a;表示該文件封裝在Ogg容器格式中&#xff08;Opus通常封裝…

在 ArcPy 腳本中進行錯誤處理和調試

查看錯誤信息 當捕獲到錯誤后&#xff0c;查看詳細的錯誤信息對于定位問題和解決問題至關重要。 &#xff08;一&#xff09;打印錯誤消息 在 except 塊中&#xff0c;可以直接打印錯誤對象來獲取錯誤消息。例如&#xff1a; try:arcpy.CalculateField_management("in…

C++11標準(4)——并發庫(多線程)

歡迎來到博主的專欄:c雜談 博主ID&#xff1a;代碼小豪 文章目錄 thread的相關函數thisthread c11新增了與并發相關的庫&#xff0c;包含線程、以及互斥、同步等與線程安全相關的庫&#xff0c;與linux中所使用POSIX庫不同&#xff0c;并發庫是將其進行了封裝&#xff0c;不再是…

優化TCP/IP協議棧與網絡層

優化TCP/IP協議棧與網絡層 在高性能架構中,網絡性能往往成為系統吞吐量與響應速度的關鍵因素之一。而TCP/IP協議棧作為現代互聯網通信的核心,其默認配置在高并發場景下常常無法滿足大規模分布式系統的性能需求。因此,架構師在構建系統時,有必要對TCP/IP協議棧及其所在的網…

Nginx常見功能

Nginx 是一個高性能的 HTTP 和反向代理服務器&#xff0c;除了基本的 Web 服務功能外&#xff0c;它還支持許多高級功能。以下是 Nginx 常用的一些功能及其設置方法&#xff1a; 1. 反向代理 反向代理是 Nginx 最常用的功能之一&#xff0c;用于將客戶端請求轉發給后端服務器&a…

UniSAL:用于組織病理學圖像分類的統一半監督主動學習方法|文獻速遞-深度學習醫療AI最新文獻

Title 題目 UniSAL: Unified Semi-supervised Active Learning for histopathologicalimage classification UniSAL&#xff1a;用于組織病理學圖像分類的統一半監督主動學習方法 01 文獻速遞介紹 組織病理學圖像在癌癥篩查、診斷及治療決策中起著關鍵作用&#xff0c;有助…

智慧園區建設資料合集(Wordppt原件)

化工園區安全風險智能化管控平臺.docx 數字孿生賦能的智慧園區物聯網云平臺建設方案.pptx 園區智慧安防解決方案.docx 新型智慧園區規劃設計方案.pptx 新型智慧園區建設方案.docx 園區大數據治理解決方案.pptx 智慧產業園區綜合解決方案.docx 智慧工業園區大數據云平臺解決方案…

好玩的鏡像匯總

一些鏡像倉庫匯總 https://github.com/code-lives/Nas-Docker https://github.com/TWO-ICE/Awesome-NAS-Docker image-matting是一款集成了AI大模型的&#xff0c;支持容器化部署的短平快摳圖工具 https://mp.weixin.qq.com/s/A1VKAYaDdbCs2o1L4ZYkSw Moodist是一個有助于專注…