Linux中死鎖問題的探討

在 Linux 中,死鎖(Deadlock) 是指多個進程或線程因為競爭資源而相互等待,導致所有相關進程或線程都無法繼續執行的狀態。死鎖是一種嚴重的系統問題,會導致系統資源浪費,甚至系統崩潰。

死鎖的定義

死鎖是指兩個或多個進程或線程在執行過程中,因為爭奪資源而造成的一種互相等待的現象。如果沒有外部干預,這些進程或線程將永遠無法繼續執行。

死鎖的四個必要條件

死鎖的發生需要同時滿足以下四個條件(稱為 Coffman 條件):

互斥條件(Mutual Exclusion)

資源一次只能被一個進程或線程占用。

例如,鎖(如互斥鎖)就是一種互斥資源。

占有并等待(Hold and Wait)

進程或線程持有至少一個資源,同時等待獲取其他被占用的資源。

非搶占條件(No Preemption)

?已分配給進程或線程的資源不能被強制剝奪,必須由其自行釋放。

循環等待條件(Circular Wait)

存在一個進程或線程的循環鏈,每個進程或線程都在等待下一個進程或線程所占用的資源。

只有當這四個條件同時滿足時,死鎖才會發生。

死鎖的示例

以下是一個典型的死鎖示例:

#include <pthread.h>
#include <stdio.h>pthread_mutex_t mutexA = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexB = PTHREAD_MUTEX_INITIALIZER;void* thread1_func(void* arg) {pthread_mutex_lock(&mutexA); // 線程1持有mutexAsleep(1); // 模擬一些操作pthread_mutex_lock(&mutexB); // 線程1嘗試獲取mutexBprintf("Thread 1 is running.\n");pthread_mutex_unlock(&mutexB);pthread_mutex_unlock(&mutexA);return NULL;
}void* thread2_func(void* arg) {pthread_mutex_lock(&mutexB); // 線程2持有mutexBsleep(1); // 模擬一些操作pthread_mutex_lock(&mutexA); // 線程2嘗試獲取mutexAprintf("Thread 2 is running.\n");pthread_mutex_unlock(&mutexA);pthread_mutex_unlock(&mutexB);return NULL;
}int main() {pthread_t tid1, tid2;pthread_create(&tid1, NULL, thread1_func, NULL);pthread_create(&tid2, NULL, thread2_func, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);return 0;
}

線程1持有 mutexA 并等待 mutexB

線程2持有 mutexB 并等待 mutexA

兩個線程互相等待,導致死鎖。

死鎖的影響

資源浪費:死鎖會導致相關進程或線程無法繼續執行,占用系統資源。

系統崩潰:如果死鎖涉及關鍵資源,可能導致整個系統無法正常運行。

難以調試:死鎖通常難以復現和調試,尤其是在復雜的多線程程序中。

如何避免死鎖

鎖順序:確保所有線程以相同的順序獲取鎖。

超時機制:為鎖操作設置超時(如 pthread_mutex_timedlock),避免無限等待。

避免嵌套鎖:盡量減少鎖的嵌套使用。

死鎖檢測:使用工具或算法檢測死鎖并采取措施。

資源分配策略:使用資源分配算法(如銀行家算法)避免死鎖。

死鎖檢測與恢復

檢測

使用工具(如 gdbvalgrind)分析程序運行狀態。

實現死鎖檢測算法(如圖的環路檢測)。

恢復

強制終止一個或多個進程或線程。

回滾操作,釋放資源并重新分配。

線程阻塞

在 Linux 中,死鎖阻塞是兩個不同的概念,盡管它們都與資源的競爭和等待有關,但它們的表現和原因有顯著區別:

阻塞(Blocking)

定義:阻塞是指一個進程或線程因為等待某個資源(如鎖、I/O 操作、信號量等)而暫時無法繼續執行,進入等待狀態。

原因

等待獲取鎖(如互斥鎖、讀寫鎖)。

等待 I/O 操作完成(如讀取文件、網絡數據)。

等待信號量或其他同步機制。

特點

阻塞是暫時的,一旦資源可用,進程或線程會被喚醒并繼續執行。

阻塞是正常的同步機制,用于協調多個進程或線程對共享資源的訪問。

阻塞不會導致系統無法運行,只是當前任務暫時停止。

示例

pthread_mutex_lock(&mutex); // 如果鎖被其他線程持有,當前線程會阻塞
// 臨界區代碼
pthread_mutex_unlock(&mutex);

區別總結

總之,阻塞是正常的同步行為,而死鎖是需要避免的系統錯誤。

線程饑餓

一個線程持有鎖一直不釋放,其他線程一直在等待這個鎖,這種情況不滿足鎖的四個必要條件,算是死鎖嗎?

比如如果一個線程持有鎖后進入死循環,且其他線程嘗試獲取該鎖。

具體過程:

  1. 線程 A 持有鎖后進入死循環,永遠不會釋放鎖。

  2. 線程 B 嘗試獲取該鎖,但由于鎖被線程 A 持有,線程 B 會一直阻塞等待。

  3. 如果還有其他線程也嘗試獲取該鎖,它們同樣會阻塞等待。

  4. 最終,這些線程會因為無法獲取鎖而永久阻塞

示例代碼如下:

#include <pthread.h>
#include <stdio.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;void* thread_func(void* arg) {pthread_mutex_lock(&mutex); // 線程 A 獲取鎖while (1) {// 死循環,永遠不會釋放鎖}pthread_mutex_unlock(&mutex); // 這行代碼永遠不會執行return NULL;
}int main() {pthread_t tid;pthread_create(&tid, NULL, thread_func, NULL);pthread_mutex_lock(&mutex); // 主線程嘗試獲取鎖,會一直阻塞printf("This will never be printed.\n");pthread_mutex_unlock(&mutex);pthread_join(tid, NULL);return 0;
}

線程 A 獲取鎖后進入死循環,永遠不會釋放鎖。

主線程嘗試獲取鎖時會被阻塞

這種情況下,雖然不滿足死鎖的四個必要條件,但它確實會導致類似死鎖的現象,通常稱為**資源饑餓(Resource Starvation)活鎖(Livelock)**的一種表現。下面詳細分析:

1. 這種情況的特點

一個線程持有鎖后一直不釋放。

其他線程因為無法獲取鎖而一直等待。

不滿足死鎖的四個必要條件(特別是循環等待條件),因為沒有多個線程相互等待。

2. 為什么不是死鎖?

死鎖的四個必要條件之一是循環等待,即存在一個進程或線程的循環鏈,每個進程或線程都在等待下一個進程或線程所占用的資源。而在你的描述中:

只有一個線程持有鎖,其他線程在等待這個鎖。

沒有形成循環等待鏈,因此不滿足死鎖的定義。

3. 這種情況的名稱

這種情況通常被稱為資源饑餓(Resource Starvation)

一個線程獨占資源(如鎖),導致其他線程無法獲取資源,從而無法繼續執行。

資源饑餓不一定是死鎖,但它會導致系統性能下降或部分功能失效。

總結下線程饑餓和死鎖的區別

比較明顯的現象就是,線程饑餓時通常會有部分線程還能執行,但是死鎖時,涉及到的所有線程都無法執行。

更多參考:

五、面試官:你講一下線程死鎖、饑餓和死循環的區別以及死鎖的處理? 我:滔滔不絕...._死鎖和循環依賴的區別-CSDN博客

常見問題

死鎖、資源饑餓、CPU飆高、內存泄漏、內存溢出、棧溢出

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

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

相關文章

【基于Mesh組網的UWB技術討論】

基于Mesh組網的UWB技術討論 Mesh 組網無線Mesh與無線中繼的區別 基于Mesh拓撲的UWB技術可行性星型拓撲 / Mesh拓撲的UWB技術比較 Mesh 組網 Mesh(網格)是一種無中心、自組織的高度業務協同的網絡。通常分為無線Mesh和有線Mesh&#xff0c;但在實際應用場景&#xff0c;有線Mes…

Python Cookbook-3.1 計算昨天和明天的日期

任務 獲得今天的日期&#xff0c;并以此計算昨天和明天的日期。 解決方案 方案一&#xff1a; 無論何時遇到有關“時間變化”或者“時間差”的問題&#xff0c;先考慮datetime包: import datetime today datetime.date.today() yesterday today - datetime.timedelta(day…

USB 模塊 全面解析(二)

本文是我整理的一些 USB 的學習心得&#xff0c;希望能對大家有所幫助。 文章目錄 前言&#x1f34d;USB 協議層數據格式&#x1f347;包格式&#x1f353; PID 域&#x1f353; 令牌包&#x1f353; 數據包&#x1f353; 握手包 &#x1f347;傳輸類型&#x1f353; 批量傳輸&…

從基礎到實踐(十):MOS管的全面解析與實際應用

MOS管&#xff08;金屬-氧化物半導體場效應晶體管&#xff09;是現代電子技術的基石&#xff0c;憑借高輸入阻抗、低功耗和易集成特性&#xff0c;成為數字電路、電源管理和信號處理的核心元件。從微處理器到新能源汽車電驅系統&#xff0c;其高效開關與放大功能支撐了計算機、…

AES/CBC/PKCS5Padding加密

1、加密代碼如下 public static String encryptAEs_CBC(String data,String key,byte[] iv) {Cipher cipher = null;try {cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//位數不夠,自動補一個長度int blocksize = cipher.getBlockSize();byte[] dataBytes …

指紋細節提取(Matlab實現)

指紋細節提取概述指紋作為人體生物特征識別領域中應用最為廣泛的特征之一&#xff0c;具有獨特性、穩定性和便利性。指紋細節特征對于指紋識別的準確性和可靠性起著關鍵作用。指紋細節提取&#xff0c;即從指紋圖像中精確地提取出能夠表征指紋唯一性的關鍵特征點&#xff0c;是…

Python 圖像處理之 Pillow 庫:玩轉圖片

哈嘍,大家好,我是木頭左! Pillow 庫作為 Python 圖像處理的重要工具之一,為提供了便捷且功能豐富的接口,讓能夠輕松地對圖像進行各種操作,從簡單的裁剪、旋轉到復雜的濾鏡應用、圖像合成等,幾乎無所不能。接下來,就讓一起深入探索如何使用 Pillow 庫來處理圖片,開啟一…

Android Flow 示例

在Android開發的世界里&#xff0c;處理異步數據流一直是一個挑戰。隨著Kotlin的流行&#xff0c;Flow作為Kotlin協程庫的一部分&#xff0c;為開發者提供了一種全新的方式來處理這些問題。今天&#xff0c;我將深入探討Flow的設計理念&#xff0c;并通過具體的例子展示如何在實…

記錄uniapp小程序對接騰訊IM即時通訊無ui集成(2)

完成以上步驟之后開始進行登錄&#xff0c;登陸就需要賬號。這個賬號我們可以在騰訊云中創建。 有了賬號之后開始去小程序進行登陸操作。騰訊云接口文檔 這里除了帳號還需要一個校驗值userSig正常項目開發這個字段可以在登陸后讓后端返回&#xff0c;現在是測試我們直接去控制…

北京航空航天大學計算機復試上機真題

北京航空航天大學計算機復試上機真題 2023北京航空航天大學計算機復試上機真題 在線評測&#xff1a;https://app2098.acapp.acwing.com.cn/ 階乘和 題目描述 求Sn1!2!3!4!5!…n!之值&#xff0c;其中n是一個數字。 輸入格式 輸入一個n&#xff08;n<20&#xff09; …

阿里萬相,正式開源

大家好&#xff0c;我是小悟。 阿里萬相正式開源啦。這就像是AI界突然開啟了一扇通往寶藏的大門&#xff0c;而且還是免費向所有人敞開的那種。 你想想看&#xff0c;在這個科技飛速發展的時代&#xff0c;AI就像是擁有神奇魔法的魔法師&#xff0c;不斷地給我們帶來各種意想…

算法之數據結構

目錄 數據結構 數據結構與算法面試題 數據結構 《倚天村 ? 圖解數據結構》 | 小傅哥 bugstack 蟲洞棧 ?數據結構基礎知識體系詳解? | Java 全棧知識體系 線性數據結構 | JavaGuide 數據結構與算法面試題 數據結構與算法面試題 | 小林coding

零基礎學習之——深度學習算法介紹01

第一節.基礎骨干網絡 物體分類是計算機視覺&#xff08;computer vision&#xff0c;CV&#xff09;中最經典的、也是目前研究得最為透徹的一 個領域&#xff0c;該領域的開創者也是深度學習領域的“名人”級別的人物&#xff0c;例如 Geoffrey Hinton、Yoshua Bengio 等。物…

弧度與角度之間的轉換公式

Radian 弧度的英語 簡稱 Rad Degree 角度的英語 簡稱 Deg 角度轉弧度 RadDeg*180/π CogMuisc.DegToRad(double degress) DegRad/180*π CogMuisc.RadToDeg(double radians) 總結: 角度大 弧度小 弧度轉角度 肯定要乘以一個大于1的數 那就是…

css之英文換行樣式

在 CSS 中&#xff0c;要實現英文文本自動換行但不從單詞中間斷開的效果&#xff0c;可以使用 word-wrap 或 overflow-wrap 屬性。以下是相關的 CSS 屬性和它們的配置&#xff1a; 使用 overflow-wrap 或 word-wrap /* This property is used to handle word breaking */ .wo…

40歲開始學Java:Java中單例模式(Singleton Pattern),適用場景有哪些?

在Java中&#xff0c;單例模式&#xff08;Singleton Pattern&#xff09;用于確保一個類只有一個實例&#xff0c;并提供全局訪問點。以下是詳細的實現方式、適用場景及注意事項&#xff1a; 一、單例模式的實現方式 1. 餓漢式&#xff08;Eager Initialization&#xff09; …

【前端基礎】3、HTML的常用元素(h、p、img、a、iframe、div、span)、不常用元素(strong、i、code、br)

HTML結構 一個HTML包含以下部分&#xff1a; 文檔類型聲明html元素 head元素body元素 例&#xff08;CSDN&#xff09;&#xff1a; 一、文檔類型聲明 HTML最一方的文檔稱為&#xff1a;文檔類型聲明&#xff0c;用于聲明文檔類型。即&#xff1a;<!DOCTYPE html>…

文本挖掘+情感分析+主題建模+K-Meas聚類+詞頻統計+詞云(景區游客評論情感分析)

本文通過情感分析技術對景區游客評論進行深入挖掘,結合數據預處理、情感分類和文本挖掘,分析游客評價與情感傾向。利用樸素貝葉斯和SVM等模型進行情感預測,探討滿意度與情感的關系。通過KMeans聚類和LDA主題分析,提取游客關心的話題,提供優化建議,為未來研究提供方向。 …

【實戰 ES】實戰 Elasticsearch:快速上手與深度實踐-2.2.2線程池配置與寫入限流

&#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 文章大綱 Elasticsearch批量寫入性能調優&#xff1a;2.2.2 線程池配置與寫入限流深度實踐1. 線程池核心機制解析1.1 Elasticsearch線程池架構1.2 Bulk線程池工作模型 2. 寫入場景線程…

VSCode 與 Vim 插件 的 復制粘貼等快捷鍵沖突,優先使用 VSCode 的快捷鍵

VSCode 與 Vim 插件 的 復制粘貼等快捷鍵沖突&#xff0c;優先使用 VSCode 的快捷鍵 在 VSCode 中&#xff0c;如果你發現 Vim 插件&#xff08;如 VSCodeVim 擴展&#xff09;與 VSCode 的默認復制粘貼快捷鍵&#xff08;CtrlC / CtrlV&#xff09;沖突&#xff0c;并且你想優…