【操作系統】死鎖

1. 定義

死鎖是指兩個或多個進程(或線程)在執行過程中,因爭奪資源而造成的一種僵局,每個進程都無限期地等待其他進程釋放它們所持有的資源。在這種情況下,沒有任何進程能夠繼續執行,除非有外部干預。

2. 死鎖的必要條件

根據Dijkstra的理論,死鎖的發生必須同時滿足以下四個必要條件:

  1. 互斥條件(Mutual Exclusion)

    • 資源不能被共享,一次只能被一個進程使用。例如,打印機、磁帶機等資源在使用時不能被多個進程同時占用。

  2. 請求與保持條件(Hold and Wait)

    • 一個進程已經持有一個資源,但又請求新的資源。如果新資源被其他進程占用,請求進程將被阻塞,但它仍然保持對已有資源的占用。

  3. 不可剝奪條件(No Preemption)

    • 資源不能被強制剝奪,只能由占用它的進程主動釋放。例如,內存資源不能被強制從一個進程轉移到另一個進程。

  4. 循環等待條件(Circular Wait)

    • 存在一個進程序列 P1?,P2?,…,Pn?,使得 P1? 等待 P2? 持有的資源,P2? 等待 P3? 持有的資源,……,Pn? 等待 P1? 持有的資源,形成一個等待環路。

3. 死鎖的示例
哲學家進餐問題

哲學家進餐問題是死鎖的經典示例。五位哲學家圍坐在一張圓桌旁,每位哲學家面前有一支叉子,左右各一支。哲學家需要同時拿起左右兩支叉子才能進餐。如果每位哲學家都先拿起左邊的叉子,然后等待右邊的叉子,最終會導致所有哲學家都餓死,因為每個人都持有一支叉子并等待另一支叉子。

銀行家算法

銀行家算法是一種預防死鎖的算法,通過資源分配圖來檢測系統是否處于安全狀態。如果系統處于安全狀態,銀行家算法會分配資源;否則,它會等待,直到系統進入安全狀態。銀行家算法通過確保系統不會進入不安全狀態來預防死鎖。

4. 死鎖的處理策略
  1. 預防死鎖(Deadlock Prevention)

    • 通過破壞死鎖的必要條件之一來預防死鎖的發生。例如:

      • 資源分級:對資源進行編號,哲學家總是先拿起編號較小的叉子,再拿起編號較大的叉子,從而破壞循環等待條件。

      • 限制資源分配:限制同時請求資源的數量,確保系統不會進入死鎖狀態。

  2. 避免死鎖(Deadlock Avoidance)

    • 動態地檢查資源分配是否會導致死鎖。例如:

      • 銀行家算法:通過資源分配圖來檢測系統是否處于安全狀態,只在安全狀態下分配資源。

  3. 檢測死鎖(Deadlock Detection)

    • 定期檢查系統是否處于死鎖狀態。如果檢測到死鎖,采取措施解決。例如:

      • 資源分配圖:通過資源分配圖檢測循環等待條件。

      • 超時機制:如果某個進程等待資源的時間超過某個閾值,認為系統可能進入死鎖狀態。

  4. 恢復死鎖(Deadlock Recovery)

    • 當檢測到死鎖時,采取措施恢復系統。例如:

      • 資源剝奪:強制剝奪某些進程持有的資源,使其能夠繼續執行。

      • 進程終止:終止某些進程,釋放其持有的資源。

5. 死鎖的示例代碼

以下是一個簡單的C語言示例,展示如何通過資源分級來預防死鎖。

?

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>#define NUM_PHILOSOPHERS 5sem_t forks[NUM_PHILOSOPHERS];void* philosopher(void* arg) {int id = *(int*)arg;int left_fork = id;int right_fork = (id + 1) % NUM_PHILOSOPHERS;while (1) {// 思考printf("Philosopher %d is thinking\n", id);sleep(1);// 餓了,嘗試拿起叉子printf("Philosopher %d is hungry\n", id);// 確保先拿起編號較小的叉子if (left_fork < right_fork) {sem_wait(&forks[left_fork]);printf("Philosopher %d picked up left fork %d\n", id, left_fork);sem_wait(&forks[right_fork]);printf("Philosopher %d picked up right fork %d\n", id, right_fork);} else {sem_wait(&forks[right_fork]);printf("Philosopher %d picked up right fork %d\n", id, right_fork);sem_wait(&forks[left_fork]);printf("Philosopher %d picked up left fork %d\n", id, left_fork);}// 吃飯printf("Philosopher %d is eating\n", id);sleep(1);// 放下叉子sem_post(&forks[right_fork]);printf("Philosopher %d put down right fork %d\n", id, right_fork);sem_post(&forks[left_fork]);printf("Philosopher %d put down left fork %d\n", id, left_fork);}
}int main() {pthread_t philosophers[NUM_PHILOSOPHERS];int ids[NUM_PHILOSOPHERS];// 初始化信號量for (int i = 0; i < NUM_PHILOSOPHERS; i++) {sem_init(&forks[i], 0, 1);}// 創建哲學家線程for (int i = 0; i < NUM_PHILOSOPHERS; i++) {ids[i] = i;pthread_create(&philosophers[i], NULL, philosopher, &ids[i]);}// 等待線程結束for (int i = 0; i < NUM_PHILOSOPHERS; i++) {pthread_join(philosophers[i], NULL);}// 清理信號量for (int i = 0; i < NUM_PHILOSOPHERS; i++) {sem_destroy(&forks[i]);}return 0;
}

代碼說明

  • 資源分級:哲學家總是先拿起編號較小的叉子,再拿起編號較大的叉子,從而破壞循環等待條件。

  • 信號量:使用信號量來控制叉子的獲取和釋放,確保資源的互斥訪問。

總結

死鎖是并發系統中一個常見的問題,通過理解死鎖的必要條件和采取適當的處理策略,可以有效地預防和解決死鎖問題。資源分級是一種簡單而有效的預防死鎖的方法,通過打破循環等待條件,確保系統不會進入死鎖狀態。

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

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

相關文章

C++入門?關于類的一些特殊知識點

涉及的關于類中的默認成員函數的知識點可以看我的這篇博客哦~ C入門必須知道的知識?類的默認成員函數&#xff0c;一文講透運用 目錄 初始化列表 類型轉換 static成員 友元 內部類 匿名對象 對象拷貝時的一些編譯器的優化 初始化列表 我們知道類中的構造函數的任務是完…

只用Prettier進行格式化項目

1.下載Prettier插件&#xff0c;禁用ESlint 2.在項目根目錄新建.prettierrc文件 {"singleQuote": true,"jsxSingleQuote": true,"printWidth": 100,"trailingComma": "none","tabWidth": 2,"semi": f…

XXL-TOOL v1.4.0 發布 | Java工具類庫

Release Notes 1、【新增】JsonRpc模塊&#xff1a;一個輕量級、跨語言遠程過程調用實現&#xff0c;基于json、http實現&#xff08;從XXL-JOB底層通訊組件提煉抽象&#xff09;。2、【新增】Concurrent模塊&#xff1a;一系列并發編程工具&#xff0c;具備良好的線程安全、高…

基于LVGL的登錄界面設計

目錄 一、演示 二、前言 三、部件知識 3.1 圖片按鈕部件 3.1.1 圖片按鈕部件的組成 3.1.2 圖片的來源 3.1.3 添加/清除的狀態 3.1.4 圖片按鈕部件 API 函數 3.2 鍵盤部件(lv_keyboard) 3.2.1 鍵盤部件的組成 3.2.2 鍵盤部件的相關知識 3.2.2.1 鍵盤部件模式 3.…

S3 跨賬戶復制:增強云中的災難恢復計劃

您準備好提升您的云和 DevOps 技能了嗎&#xff1f; &#x1f425;《云原生devops》專門為您打造&#xff0c;我們精心打造的 30 篇文章庫&#xff0c;這些文章涵蓋了 Azure、AWS 和 DevOps 方法論的眾多重要主題。無論您是希望精進專業知識的資深專業人士&#xff0c;還是渴望…

線程與進程深度解析:從fork行為到生產者-消費者模型

線程與進程深度解析&#xff1a;從fork行為到生產者-消費者模型 一、多線程環境下的fork行為與線程安全 1. 多線程程序中fork的特殊性 核心問題&#xff1a;fork后子進程的線程模型 當多線程程序中的某個線程調用fork時&#xff1a; 子進程僅包含調用fork的線程&#xff1…

Circular Plot系列(五): circle plot展示單細胞互作

這是我們circle系列的最后一節&#xff0c;我想常見的弦圖是繞不開的&#xff0c;所以最后從前面介紹的circle plot思路&#xff0c;做一遍弦圖。其實前面的內容如果消化了&#xff0c;plot互作弦圖也就不成什么問題了。 效果如下&#xff1a; #cellchat提取互作結果&#xff…

(11)Vue-Router路由的詳細使用

本系列教程目錄&#xff1a;Vue3Element Plus全套學習筆記-目錄大綱 文章目錄 第2章 路由 Vue-Router2.1 Vue路由快速入門2.1.1 創建項目2.1.2 路由運行流程 2.2 傳遞參數-useRoute2.2.1 路徑參數-params1&#xff09;普通傳參2&#xff09;傳遞多個參數3&#xff09;對象方式傳…

react + antd 實現后臺管理系統

文章目錄 完整路由搭建Layout 和 Aside組件引入 AntdAside組件實現 項目效果圖 項目完整代碼地址 https://gitee.com/lyh1999/react-back-management 項目完整代碼地址 react依賴安裝 最好采用yarn 安裝 react-router 安裝依賴 配置路由 history模式 / // src/router/…

基于AWS Marketplace的快速解決方案:從選型到部署實戰

1. 引言&#xff1a;為什么選擇AWS Marketplace&#xff1f; 在數字化轉型的背景下&#xff0c;企業需要快速獲取成熟的軟件工具和服務以降低開發成本。AWS Marketplace 作為亞馬遜云科技的官方應用商店&#xff0c;提供超過萬款預配置的第三方和AWS原生解決方案&#xff0c;涵…

2021年第十二屆藍橋杯省賽B組C++題解

2021年第十二屆藍橋杯省賽B組C題解 關鍵詞&#xff1a;藍橋杯、省賽、題解、C、算法 一、個人見解 第十二屆藍橋杯省賽B組共有10道題目&#xff0c;包含5道填空題&#xff08;T1-T5&#xff09;和5道編程題&#xff08;T6-T10&#xff09;&#xff0c;總分150分。比賽時長4小…

日語學習-日語知識點小記-進階-JLPT-N1階段(1):語法單詞

日語學習-日語知識點小記-進階-JLPT-N1階段&#xff08;1&#xff09;&#xff1a;語法單詞 1、前言&#xff08;1&#xff09;情況說明&#xff08;2&#xff09;工程師的信仰&#xff08;3&#xff09;高級語法N1語法和難點一、N1語法學習內容&#xff08;高級語法&#xff…

Python|Pyppeteer實現自動登錄小紅書(32)

前言 本文是該專欄的第32篇,結合優質項目案例持續分享Pyppeteer的干貨知識,記得關注。 本文中,筆者以小紅書為例,基于Pyppeteer實現自動登錄“小紅書”。 需要注意的是,對Pyppeteer不太熟悉的同學,可往前翻閱本專欄前面介紹的Pyppeteer知識點,本專欄將帶你了解并熟練使…

【翻譯、轉載】【轉載】LLM 的函數調用與 MCP

來源&#xff1a; https://www.dailydoseofds.com/p/function-calling-mcp-for-llms/ 【代碼以圖像顯示的是原文內容&#xff0c;以代碼形式顯示的是大模型給出的參考】 LLM 的函數調用與 MCP 在 MCP 變得像現在這樣主流&#xff08;或流行&#xff09;之前&#xff0c;大多…

【QT】QT中http協議和json數據的解析-http獲取天氣預報

QT中http協議和json數據的解析 1.http協議的原理2.QT中http協議的通信流程2.1 方法步驟 3.使用http協議&#xff08;通過http下載圖片和獲取天氣預報信息&#xff09;3.1 http下載網絡上的圖片(下載小文件)3.1.1 示例代碼3.1.2 現象 3.2 獲取網絡上天氣預報3.2.1 免費的天氣預報…

hot100:鏈表倒數k個節點- 力扣(LeetCode)

題目&#xff1a; 實現一種算法&#xff0c;找出單向鏈表中倒數第 k 個節點。返回該鏈表中倒數第k個節點。 示例一&#xff1a; 輸入&#xff1a;{1,2,3,4,5},2 返回值&#xff1a;{4,5} 說明&#xff1a;返回倒數第2個節點4&#xff0c;系統會打印后面所有的節點來比較。 …

Spring AI 實戰:第十一章、Spring AI Agent之知行合一

引言:智能體的知行辯證法 “知為行之始,行為知之成”,王陽明的哲學智慧在AI時代煥發光彩。智能體(LLM Agent)的進化之路,正是"認知-決策-執行"這一閉環的完美詮釋: 知明理:融合大語言模型的推理能力與知識圖譜的結構化認知行致用:基于ReAct模式的動態工具調…

365打卡第R6周: LSTM實現糖尿病探索與預測

&#x1f368; 本文為&#x1f517;365天深度學習訓練營中的學習記錄博客 &#x1f356; 原作者&#xff1a;K同學啊 &#x1f3e1; 我的環境&#xff1a; 語言環境&#xff1a;Python3.10 編譯器&#xff1a;Jupyter Lab 深度學習環境&#xff1a;torch2.5.1 torchvision0…

W-TinyLFU緩存驅逐算法解析

文章目錄 1. 背景與概述1.1 什么是緩存驅逐算法1.2 W-TinyLFU 的定義與價值 2. 核心思想與設計理念2.1 時間局部性與頻率局部性的結合2.2 高效的頻率統計2.3 窗口機制的引入 3. 架構設計與組件3.1 整體架構3.2 窗口緩存&#xff08;Window Cache&#xff09;3.3 主緩存&#xf…

[特殊字符] 人工智能大模型之開源大語言模型匯總(國內外開源項目模型匯總) [特殊字符]

Large Language Model (LLM) 即大規模語言模型&#xff0c;是一種基于深度學習的自然語言處理模型&#xff0c;它能夠學習到自然語言的語法和語義&#xff0c;從而可以生成人類可讀的文本。 所謂 "語言模型"&#xff0c;就是只用來處理語言文字&#xff08;或者符號…