【操作系統-Day 25】死鎖 (Deadlock):揭秘多線程編程的“終極殺手”

Langchain系列文章目錄

01-玩轉LangChain:從模型調用到Prompt模板與輸出解析的完整指南
02-玩轉 LangChain Memory 模塊:四種記憶類型詳解及應用場景全覆蓋
03-全面掌握 LangChain:從核心鏈條構建到動態任務分配的實戰指南
04-玩轉 LangChain:從文檔加載到高效問答系統構建的全程實戰
05-玩轉 LangChain:深度評估問答系統的三種高效方法(示例生成、手動評估與LLM輔助評估)
06-從 0 到 1 掌握 LangChain Agents:自定義工具 + LLM 打造智能工作流!
07-【深度解析】從GPT-1到GPT-4:ChatGPT背后的核心原理全揭秘
08-【萬字長文】MCP深度解析:打通AI與世界的“USB-C”,模型上下文協議原理、實踐與未來

Python系列文章目錄

PyTorch系列文章目錄

機器學習系列文章目錄

深度學習系列文章目錄

Java系列文章目錄

JavaScript系列文章目錄

Python系列文章目錄

Go語言系列文章目錄

Docker系列文章目錄

操作系統系列文章目錄

01-【操作系統-Day 1】萬物之基:我們為何離不開操作系統(OS)?
02-【操作系統-Day 2】一部計算機的進化史詩:操作系統的發展歷程全解析
03-【操作系統-Day 3】新手必看:操作系統的核心組件是什么?進程、內存、文件管理一文搞定
04-【操作系統-Day 4】揭秘CPU的兩種工作模式:為何要有內核態與用戶態之分?
05-【操作系統-Day 5】通往內核的唯一橋梁:系統調用 (System Call)
06-【操作系統-Day 6】一文搞懂中斷與異常:從硬件信號到內核響應的全流程解析
07-【操作系統-Day 7】程序的“分身”:一文徹底搞懂什么是進程 (Process)?
08-【操作系統-Day 8】解密進程的“身份證”:深入剖析進程控制塊 (PCB)
09-【操作系統-Day 9】揭秘進程狀態變遷:深入理解就緒、運行與阻塞
10-【操作系統-Day 10】CPU的時間管理者:深入解析進程調度核心原理
11-【操作系統-Day 11】進程調度算法揭秘(一):簡單公平的先來先服務 (FCFS) 與追求高效的短作業優先 (SJF)
12-【操作系統-Day 12】調度算法核心篇:詳解優先級調度與時間片輪轉 (RR)
13-【操作系統-Day 13】深入解析現代操作系統調度核心:多級反饋隊列算法
14-【操作系統-Day 14】從管道到共享內存:一文搞懂進程間通信 (IPC) 核心機制
15-【操作系統-Day 15】揭秘CPU的“多面手”:線程(Thread)到底是什么?
16-【操作系統-Day 16】揭秘線程的幕后英雄:用戶級線程 vs. 內核級線程
17-【操作系統-Day 17】多線程的世界:深入理解線程安全、創建銷毀與線程本地存儲 (TLS)
18-【操作系統-Day 18】進程與線程:從概念到實戰,一文徹底搞懂如何選擇
19-【操作系統-Day 19】并發編程第一道坎:深入理解競態條件與臨界區
20-【操作系統-Day 20】并發編程基石:一文搞懂互斥鎖(Mutex)、原子操作與自旋鎖
21-【操作系統-Day 21】從互斥鎖到信號量:掌握更強大的并發同步工具Semaphore
22-【操作系統-Day 22】經典同步問題之王:生產者-消費者問題透徹解析(含代碼實現)
23-【操作系統-Day 23】經典同步問題之讀者-寫者問題:如何實現讀寫互斥,讀者共享?
24-【操作系統-Day 24】告別信號量噩夢:一文搞懂高級同步工具——管程 (Monitor)
25-【操作系統-Day 25】死鎖 (Deadlock):揭秘多線程編程的“終極殺手”


文章目錄

  • Langchain系列文章目錄
  • Python系列文章目錄
  • PyTorch系列文章目錄
  • 機器學習系列文章目錄
  • 深度學習系列文章目錄
  • Java系列文章目錄
  • JavaScript系列文章目錄
  • Python系列文章目錄
  • Go語言系列文章目錄
  • Docker系列文章目錄
  • 操作系統系列文章目錄
  • 摘要
  • 一、什么是死鎖 (Deadlock)?
    • 1.1 生活中的死喻:一個十字路口的交通僵局
    • 1.2 專業的定義
    • 1.3 死鎖的危害
  • 二、經典案例:哲學家就餐問題 (Dining Philosophers Problem)
    • 2.1 問題描述
    • 2.2 死鎖的產生過程
    • 2.3 問題的啟示
  • 三、死鎖的四大“元兇”:產生的必要條件
    • 3.1 互斥條件 (Mutual Exclusion)
      • 3.1.1 定義
      • 3.1.2 解析
    • 3.2 持有并等待條件 (Hold and Wait)
      • 3.2.1 定義
      • 3.2.2 解析
    • 3.3 非搶占條件 (No Preemption)
      • 3.3.1 定義
      • 3.3.2 解析
    • 3.4 循環等待條件 (Circular Wait)
      • 3.4.1 定義
      • 3.4.2 解析
  • 四、理解四大條件的“合謀”
  • 五、總結


摘要

在并發編程的世界里,線程與進程的協作帶來了前所未有的效率,但同時也引入了一系列復雜的挑戰。其中,死鎖 (Deadlock) 無疑是其中最棘手、也最致命的問題之一。它像一個無形的幽靈,能讓一個看似健壯的系統瞬間陷入停滯,所有相關的進程都無限期地等待著永遠不會到來的資源。本文將作為您深入理解死鎖的向導,首先通過生動的現實生活比喻和經典的“哲學家就餐問題”來直觀地揭示什么是死鎖。隨后,我們將系統性地剖析導致死鎖產生的四個缺一不可的必要條件——互斥、持有并等待、非搶占和循環等待。理解這些根源,是后續學習如何預防、避免和解決死鎖問題的基石。

一、什么是死鎖 (Deadlock)?

在探討如何解決一個問題前,我們必須先清晰地定義它。死鎖,在計算機科學中是一個極其重要的概念,尤其是在多任務和多線程環境中。

1.1 生活中的死喻:一個十字路口的交通僵局

想象一個沒有紅綠燈的十字路口,四輛汽車從四個方向同時到達路口中心,每一輛車都想繼續前進,但它的去路被右邊的車擋住了。

  • 車A 想前進,但被 車B 擋住。
  • 車B 想前進,但被 車C 擋住。
  • 車C 想前進,但被 車D 擋住。
  • 車D 想前進,但被 車A 擋住。

此刻,一個完美的僵局形成了。沒有一輛車可以移動,因為它們都在等待一個被其他車輛占用的空間,而占用空間的車輛又在等待另一個… 這種“你等我,我等你”的無限循環等待,就是死鎖最直觀的體現。除非有外力介入(比如交警指揮),否則這個僵局將永遠持續下去。

1.2 專業的定義

在操作系統中,死鎖的定義更為嚴謹:

死鎖 (Deadlock) 是指在一個進程集合中,每個進程都在等待一個只有該集合中其他進程才能引發的事件,從而導致所有進程都無法向前推進的系統狀態。

簡單來說,就是多個進程或線程因爭奪共享資源而陷入的一種永久性的阻塞狀態。這些“資源”可以是硬件設備(如打印機、掃描儀)、軟件資源(如數據庫記錄、文件鎖),或者是任何在同一時刻只能被一個進程使用的對象(如互斥鎖)。

1.3 死鎖的危害

死鎖被稱為并發編程的“終極殺手”并非危言聳聽。它的危害是巨大的:

  • 系統響應性喪失:涉及死鎖的進程將永久掛起,無法完成其任務,導致應用程序或整個系統停止響應。
  • 資源浪費:死鎖的進程會一直持有它們已經獲得的資源,而這些資源無法被其他進程使用,造成了嚴重的資源浪費。
  • 系統崩潰:在某些關鍵系統中,如果核心進程發生死鎖,可能會導致整個操作系統崩潰。

正因為其危害性,理解并處理死鎖是每一位系統程序員和應用開發者的必備技能。

二、經典案例:哲學家就餐問題 (Dining Philosophers Problem)

為了更具體地理解死鎖在計算機系統中的表現,我們來看一個由計算機科學家 Edsger Dijkstra 提出的經典同步問題——哲學家就餐問題。

2.1 問題描述

假設有五位哲學家,他們圍坐在一張圓桌旁,桌上放著五支筷子,每兩位哲學家之間放一支。哲學家的生活很簡單,只有兩件事:思考和吃飯。

  • 思考:哲學家思考時,不需要任何餐具。
  • 吃飯:當哲學家感到饑餓時,他必須同時拿起他左手邊右手邊的兩支筷子才能吃飯。吃完后,他會放下這兩支筷子,繼續思考。

這里的 哲學家 可以看作是系統中的 進程/線程,而 筷子 則是需要競爭的 共享資源

2.2 死鎖的產生過程

現在,讓我們設想一種最糟糕的情況:

  1. 第一步:五位哲學家同時感到饑餓,并決定吃飯。
  2. 第二步:每一位哲學家都非常“有禮貌”地先拿起了他左手邊的筷子。
  3. 第三步:當他們試圖去拿右手邊的筷子時,發現筷子已經被鄰座的哲學家拿走了。

此刻,僵局形成:

  • 哲學家1:持有筷子1,等待筷子2。
  • 哲學家2:持有筷子2,等待筷子3。
  • 哲學家3:持有筷子3,等待筷子4。
  • 哲學家4:持有筷子4,等待筷子5。
  • 哲學家5:持有筷子5,等待筷子1。

每一位哲學家都持有了一支筷子,同時又在等待另一支被他人持有的筷子。一個完美的閉環等待鏈形成了,沒有人能成功拿到第二支筷子,也就沒有人能吃飯,更沒有人會放下手中的筷子。他們將永遠地等待下去——這就是一個典型的死鎖場景。

2.3 問題的啟示

哲學家就餐問題絕不僅僅是一個思想實驗。它精準地模擬了多線程環境下資源競爭的真實困境。例如,一個程序中的兩個線程需要同時鎖定兩個資源(比如兩個數據庫表 A 和 B)才能繼續工作。

  • 線程1:成功鎖定了資源 A,然后嘗試鎖定資源 B。
  • 線程2:與此同時,成功鎖定了資源 B,然后嘗試鎖定資源 A。

結果,線程1持有A等待B,線程2持有B等待A,兩者都無法前進,死鎖發生。

三、死鎖的四大“元兇”:產生的必要條件

通過上面的例子,我們對死鎖有了直觀感受。那么,從理論上講,一個死鎖的發生,必須同時滿足以下四個條件。它們被稱為死鎖的必要條件,缺一不可。

3.1 互斥條件 (Mutual Exclusion)

3.1.1 定義

互斥條件指一個資源在任意時刻只能被一個進程所使用。如果其他進程請求該資源,則請求者必須等待,直到資源被釋放。

3.1.2 解析

這是許多資源固有的屬性。例如,打印機在同一時間只能打印一個文檔,一個文件的寫操作在同一時間只能由一個進程執行,一個互斥鎖(Mutex)的核心作用就是保證互斥。如果資源可以被共享,那么自然就不會因爭奪它而產生死鎖。

// 偽代碼示例:互斥鎖保證了printer資源一次只能被一個線程訪問
Mutex printerLock = new Mutex();void printJob() {printerLock.lock(); // 獲取鎖,實現互斥try {// ...執行打印操作...} finally {printerLock.unlock(); // 釋放鎖}
}

這個條件是死鎖的基礎,但僅有互斥是不足以構成死鎖的。

3.2 持有并等待條件 (Hold and Wait)

3.2.1 定義

持有并等待條件指一個進程至少持有一個資源,并且正在等待獲取其他進程持有的額外資源。

3.2.2 解析

回到十字路口的例子,每輛車都持有了自己當前所在的路口位置(資源1),同時等待進入前方的路口位置(資源2)。在哲學家就餐問題中,每位哲學家都持有了左手的筷子,同時等待右手的筷子。

這個條件描述了一種“得寸進尺”的資源請求策略。如果進程在請求新資源前不持有任何資源,或者可以一次性申請到所有需要的資源,那么這個條件就不會滿足。

// 偽代碼示例:經典的死鎖模式
// Thread A
synchronized(resourceA) { // 持有資源ASystem.out.println("Thread A got resource A, waiting for B...");Thread.sleep(100); synchronized(resourceB) { // 等待資源B// ...}
}// Thread B
synchronized(resourceB) { // 持有資源BSystem.out.println("Thread B got resource B, waiting for A...");synchronized(resourceA) { // 等待資源A// ...}
}

3.3 非搶占條件 (No Preemption)

3.3.1 定義

非搶占條件指資源不能被強制地從持有它的進程中搶占過來。資源只能在進程使用完畢后,由其自愿釋放。

3.3.2 解析

如果資源可以被搶占,那么死鎖問題就容易解決了。例如,在十字路口僵局中,如果交警可以命令其中一輛車“退后”(搶占它占用的路口位置),僵局就可以被打破。

在操作系統中,如果一個進程持有某些資源,并且請求另一個無法立即獲得的資源,系統不能強行拿走它已經持有的資源。這保證了進程狀態的穩定性,但也為死鎖的形成提供了土壤。

3.4 循環等待條件 (Circular Wait)

3.4.1 定義

循環等待條件指存在一個進程-資源的循環鏈,使得進程集合 {P0,P1,...,Pn}\{P_0, P_1, ..., P_n\}{P0?,P1?,...,Pn?} 中的 P0P_0P0? 正在等待 P1P_1P1? 持有的資源,P1P_1P1? 正在等待 P2P_2P2? 持有的資源,…,PnP_nPn? 正在等待 P0P_0P0? 持有的資源。

3.4.2 解析

這是死鎖形成的閉環。上述三個條件共同構成了死鎖的潛在環境,而循環等待則是將這些潛在風險“點燃”的導火索。

我們可以用資源分配圖來清晰地展示這個關系:

  • 進程 P1 持有 資源 R1,請求 資源 R2
  • 進程 P2 持有 資源 R2,請求 資源 R1

這就形成了一個循環等待:P1 -> R2 -> P2 -> R1 -> P1

哲學家就餐問題中,等待鏈是 哲學家1 -> 筷子2 -> 哲學家2 -> 筷子3 -> ... -> 哲學家5 -> 筷子1 -> 哲學家1

四、理解四大條件的“合謀”

理解這四個條件的最佳方式是將它們視為一樁“懸案”的四個犯罪要素。只有當這四個要素同時在場,犯罪(死鎖)才會發生。

必要條件含義現實世界類比(十字路口)
互斥 (Mutual Exclusion)資源獨占一個路口位置一次只能容納一輛車。
持有并等待 (Hold and Wait)占著碗里的,看著鍋里的汽車已占據當前路口,同時等待下一個路口。
非搶占 (No Preemption)資源不能被強行拿走除非司機自愿,否則不能強行讓車后退。
循環等待 (Circular Wait)形成等待閉環A等B,B等C,C等D,D等A。

這四個條件是必要條件,意味著只要發生死鎖,這四個條件必定同時成立。反之,只要我們能破壞其中任意一個條件,死鎖就永遠不會發生。這為我們后續探討死鎖的預防和避免策略指明了方向。

五、總結

本文深入探討了操作系統中一個至關重要且極具挑戰性的問題——死鎖。通過本次學習,我們應掌握以下核心知識點:

  1. 死鎖的本質:死鎖是多個進程或線程因互相等待對方持有的資源而陷入的一種永久性阻塞狀態,導致系統無法繼續正常工作。
  2. 經典模型:“哲學家就餐問題”生動地模擬了并發環境下資源競爭導致死鎖的場景,是理解死鎖機理的經典案例。
  3. 死鎖的四大必要條件:死鎖的發生必須同時滿足四個條件,它們分別是:
    • 互斥條件:資源一次只能被一個進程使用。
    • 持有并等待條件:進程持有至少一個資源,并請求新的資源。
    • 非搶占條件:已分配的資源不能被強制剝奪。
    • 循環等待條件:存在一個進程-資源的循環等待鏈。
  4. 條件的必要性:這四個條件是死鎖發生的“鐵證”。在后續的學習中,我們將了解到,所有處理死鎖的策略,無論是預防、避免還是檢測,其根本思想都是圍繞著如何破壞這四個條件之一或多??個展開的。

理解死鎖的成因是邁向高級并發編程的第一步。在接下來的文章中,我們將繼續探討如何“拆解”這個定時炸彈,學習預防、避免、檢測和解除死鎖的具體技術和算法。


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

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

相關文章

【嵌入式C語言】七

8.4函數的聲明和定義聲明一個函數意味著向編譯器描述函數名、返回值、參數個數和類型,但并不會為函數分配存儲空間定義一個函數意味著在聲明變量的同時還要有具體的實現,并且會為函數分配存儲空間8.5多源文件的函數聲明和定義8.6預處理指令#Include#incl…

hardhat3 源神 -- 啟動!

Hardhat 項目開發環境搭建完整指南 1. 從 GitHub 下載項目 # 使用 SSH 方式克隆(需要配置 SSH key) git clone gitgithub.com:NomicFoundation/hardhat.git# 或使用 HTTPS 方式 git clone https://github.com/NomicFoundation/hardhat.git# 進入項目目錄…

遇到 Git 提示大文件無法上傳確實讓人頭疼

遇到 Git 提示大文件無法上傳確實讓人頭疼,但別擔心,我們可以一步步來解決。為了讓你更清晰地了解整個流程,我先用一個表格來概括主要步驟:步驟核心操作關鍵命令/工具示例 (用于刪除歷史中的大文件)1. 定位大文件使用 Git 命令或工…

機器人控制器開發(傳感器層——奧比大白相機適配)

編譯OrbbecSDK_ROS2的代碼 執行命令 colcon buildros2 launch orbbec_camera dabai.launch.py問題1: 運行時報錯: [component_container-1] [ERROR] [1757153916.450795107] [camera.camera_container]: Failed to load library: Could not load library…

C語言(長期更新)第15講 指針詳解(五):習題實戰

C語言(長期更新)第15講 指針詳解(五):習題實戰 跟著潼心走,輕松拿捏C語言,困惑通通走,一去不回頭~歡迎開始今天的學習內容,你的支持就是博主最大的動力。博主主頁&#…

數據倉庫概要

什么是數據倉庫? 數據倉庫是一個面向主題的、集成的、相對穩定的、反映歷史變化的數據集合,用于支持管理決策。 核心特征 1. 面向主題 數據倉庫圍繞核心業務主題(如客戶、產品、銷售、財務)來組織數據,而不是圍繞具體的…

python庫 Py2exe 的詳細使用(將 Python 腳本變為Windows獨立軟件包)

更多內容請見: python3案例和總結-專欄介紹和目錄 文章目錄 一、Py2exe 概述 1.1 Py2exe介紹 1.2 Py2exe安裝 1.3 替代工具推薦 二、基礎使用 2.1 編寫打包腳本 2.2 執行打包命令 2.3 完整案例 2.4 配置選項詳解 2.5 構建和分發 三、高級配置 3.1 包含隱藏導入 3.2 處理特殊包…

CuTe C++ 簡介02,gemm_device cuda kernel 的實現

《CuTe C 簡介01,從示例開始 》 中,最后看到了 計算 gemm 的cuda kernel,使用 NVIDIA CUTLASS 的 CUTe (CUDA Tile) 庫實現的高性能 GEMM (通用矩陣乘法) CUDA kernel。接下來解釋一下這個內核的各個部分。文末再貼一遍代碼,方便查…

萬代《寶可夢》主題新品扭蛋公開!史上最大尺寸

使用jQuery的常用方法與返回值分析 jQuery是一個輕量級的JavaScript庫,旨在簡化HTML文檔遍歷和操作、事件處理以及動畫效果的創建。本文將介紹一些常用的jQuery方法及其返回值,幫助開發者更好地理解和運用這一強大的庫。 1. 選擇器方法 jQuery提供了多種…

【FastDDS】Layer Transport ( 05-Shared Memory Transport)

6.4 共享內存傳輸 共享內存(SHM)傳輸依靠主機操作系統提供的共享內存機制,實現了在同一處理單元/機器上運行的實體之間的快速通信。注意 Fast DDS 利用域參與者(DomainParticipant)的 GuidPrefix_t 來識別在同一主機上…

記 2025/9/6

人工智能常見的模型按照處理問題分為6大類:處理權重問題的權重模型、處理狀態問題的狀態模型、處理序列問題的問題模型、處理表示問題的表示模型、處理相似度的相似模型、處理分類問題的分類模型。權重是計算特定狀態下事物的重要性。狀態問題是刻畫權重動態變化的過…

開啟Python之路,第一節學習大綱-從入門到進階

前端開啟Python之路,前端有沒有必要卷后端技術,歡迎各位大神批評指正 第一階段:基礎入門 (打好根基) 目標: 理解編程基本概念,掌握 Python 核心語法,能編寫簡單的腳本程序。 1、環境搭建與開發工具 安裝 Py…

webshell及冰蝎雙擊無法打開?

什么是webshell? web:萬維網 shell:是指一種應用程序,為用戶和系統之間建立連接,通過這個界面訪問操作系統內核的服務 webshell:是以asp、aspx、php、jsp或者cgi等網頁文件形式存在的一種命令執行環境,也可以將其稱做…

【星閃】Hi2821 | PWM脈寬調制模塊 + 呼吸燈例程

1. 簡介PWM(Pulse Width Modulation),全稱脈寬調制,通過對一系列脈沖的寬度進行調制,等效出所需波形。即對模擬信號電平進行數字編碼,通過調節頻率、占空比的變化來調節信號的變化。一個 PWM 周期內由一段高…

51單片機---硬件學習(電子琴、主從應答模式、modbus模型、DS18B20傳感器顯示溫度)

一、串行通信與并行通信1、串行通信定義:數據一位一位地按順序通過單條傳輸線進行傳輸的通信方式。優點:傳輸線少,成本低,適合長距離傳輸缺點:傳輸速度相對較慢2、并行通信定義:數據的各位同時通過多條并行…

SpringBoot后端開發常用工具詳細介紹——SpringSecurity認證用戶保證安全

簡單的開始 創建SpringBoot項目 首先創建一個簡單的springboot項目,假設端口為8888,添加controller控制層,并在其中添加TestController控制類,那么啟動springboot項目之后,訪localhost:8888/api/message頁面會顯示my…

別再手工縫合API了!開源LLMOps神器LMForge,讓你像搭積木一樣玩轉AI智能體!

你是否受夠了這些? 剛調通OpenAI的API,老板說“咱們試試國產模型降本增效”,你看著滿屏的if-else只想說“我暈”。想給AI加上“查天氣”、“執行代碼”的能力,卻發現Function Calling的代碼復雜得讓人頭皮發麻。本地的Agentdemo驚…

window使用ffmep工具,加自定義腳本執行視頻轉碼成h264(運營人員使用)

技術文章大綱:ffmep配合腳本使用1. 需要提供腳本給視頻轉碼的給運營,給運營上傳視頻使用安裝ffmep windows版本(目前我使用的就是windows)將腳本里面的執行路徑修改成自己的電腦安裝ffmep/bin/ffmep.exe路徑處理好之后就點擊執行2.環境準備ffmep windows版解壓到一個…

Leetcode 240. 搜索二維矩陣 II 矩陣 / 二分

原題鏈接&#xff1a; Leetcode 240. 搜索二維矩陣 II 解法一&#xff1a;排除法 參考 【圖解】排除法&#xff0c;一圖秒懂&#xff01;&#xff08;Python/Java/C/C/Go/JS/Rust&#xff09; 從右上角&#xff1a; class Solution { public:bool searchMatrix(vector<vec…

OCR 證件識別:驅動澳門酒店自助入住智能化

澳門酒店作為國際旅游窗口&#xff0c;每日接待持多元證件的旅客&#xff0c;OCR 證件識別技術的應用&#xff0c;讓自助入住終端實現 “一證通辦”&#xff0c;大幅提升服務效率。?旅客在自助終端辦理入住時&#xff0c;只需將護照、港澳通行證、回鄉證、電子身份證等證件貼近…