最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ 死鎖檢測基礎(chǔ)思路詳解

 更新時間:2026年03月04日 14:51:40   作者:幽默代碼人  
文章介紹了C++中死鎖檢測的基本思路,包括理論部分的死鎖概念、產(chǎn)生條件以及檢測方法,以及實現(xiàn)部分的核心數(shù)據(jù)結(jié)構(gòu)、邏輯和鉤子機(jī)制,感興趣的朋友跟隨小編一起看看吧

一、理論部分

死鎖(Deadlock)是并發(fā)編程中最棘手的問題之一。不同于內(nèi)存泄漏可以通過工具最終定位,死鎖一旦發(fā)生,往往導(dǎo)致系統(tǒng)徹底卡死,且難以復(fù)現(xiàn)。

死鎖的現(xiàn)象舉一個簡單的例子,如下圖所示,3個線程都在運行,且圖中資源均一次只能被一個線程占用,線程A占用資源1,線程B占用資源2,線程C占用資源3,此時線程A不釋放資源1且想去占用資源2,而線程B也不釋放資源2并且想去占用資源3,而線程C同樣不釋放資源3去占用資源1。這樣,線程A, B, C 都因為獲取不到足夠的資源而一直陷入等待狀態(tài)。這種現(xiàn)象就是死鎖。

死鎖產(chǎn)生的四個必要條件,也就是死鎖產(chǎn)生的原因如下,缺一不可:

條件說明
互斥條件資源一次只能被一個線程占用
持有且等待線程持有資源同時請求新資源
不可搶占資源不能被強(qiáng)制釋放
循環(huán)等待形成線程-資源的循環(huán)鏈

這四個必要條件,只要打破一個,就不會形成死鎖,但一般來說我們不會去打破第一個互斥條件,因為這一般是資源自帶的性質(zhì),我們無法避免。比如說買票時的車票數(shù),不同人看到的剩余票數(shù)應(yīng)該是一致的,這無法避免。

而要打破死鎖,首先需要的是檢測到死鎖。那么如何檢測呢?回到剛才的圖我們可以發(fā)現(xiàn),形成死鎖后圖中出現(xiàn)了環(huán),也就是說我們可以將線程與資源占用關(guān)系抽象成圖之后,檢測圖中是否形成環(huán)回路,只要有環(huán),那就出現(xiàn)了死鎖,進(jìn)而采取下一步操作。

二、實現(xiàn)部分

我們在此僅實現(xiàn)一個簡易化的版本,由于理解死鎖檢測。

1. 數(shù)據(jù)結(jié)構(gòu)設(shè)計

核心數(shù)據(jù)結(jié)構(gòu)

struct source_type {
    uint64 id;          // 線程ID或鎖地址
    enum Type type;     // 類型:PROCESS 或 RESOURCE(雖然代碼中只用到了PROCESS)
    uint64 lock_id;     // 鎖ID(用于locklist)
    int degress;        // 鎖的等待計數(shù)
};
struct vertex {
    struct source_type s;  // 頂點數(shù)據(jù)
    struct vertex *next;   // 鄰接表指針
};

任務(wù)圖(等待圖)

struct task_graph {
    struct vertex list[MAX];      // 頂點數(shù)組(鄰接表頭)
    int num;                      // 頂點數(shù)量
    struct source_type locklist[MAX]; // 鎖持有表
    int lockidx;                  // 鎖數(shù)量
    pthread_mutex_t mutex;        // 保護(hù)圖結(jié)構(gòu)的鎖(實際未使用)
};
  • 鄰接表:list[MAX] 存儲所有線程頂點,next 指向該線程等待的其他線程
  • 鎖持有表:記錄每個鎖當(dāng)前被哪個線程持有

2. 核心邏輯

核心規(guī)則

代碼的邏輯是當(dāng)線程1想要持有鎖時,先查詢鎖持有表,如果鎖沒有被占用,那就直接使用鎖并在鎖持有表中新增一條對應(yīng)的記錄。如果鎖被占用了,就在圖中連一條指向占有線程2的邊。

當(dāng)線程T1試圖獲取已被T2持有的鎖L時:
    添加邊:T1 → T2
    表示T1在等待T2釋放鎖

三個關(guān)鍵函數(shù)(部分偽代碼)

// 1. 加鎖前:如果鎖已被其他線程持有,建立等待關(guān)系
void lock_before(tid, lockaddr) {
    if (鎖已被其他線程T2持有) {
        添加邊:當(dāng)前線程T1 → T2
        lock.degress++  // 等待計數(shù)增加
    }
}
// 2. 加鎖后:更新鎖的持有者
void lock_after(tid, lockaddr) {
    if (鎖是空閑的) {
        記錄當(dāng)前線程持有該鎖
    } else {
        移除之前建立的等待邊(因為已經(jīng)獲得鎖)
        更新鎖的持有者為當(dāng)前線程
    }
}
// 3. 解鎖后:如果沒人等待,清空鎖記錄
void unlock_after(tid, lockaddr) {
    if (鎖的degress == 0) {
        清空鎖的持有信息
    }
}

3. 死鎖檢測算法

在以上接口的基礎(chǔ)上,我們再添加一個檢測圖中環(huán)的算法就能實現(xiàn)死鎖檢測。最暴力的做法是使用DFS 但不推薦。推薦使用 Tarjan 算法來檢測環(huán),一個環(huán)一定是一個有向圖的一個強(qiáng)連通分量,通過這個性質(zhì)來實現(xiàn)死鎖檢測。

4. 鉤子機(jī)制(Hooking)

最后是通過鉤子機(jī)制獲取并修改原始函數(shù)指針,將pthread_mutex_lock和pthread_mutex_unlock改寫邏輯:

// hook
// define
typedef int (*pthread_mutex_lock_t)(pthread_mutex_t *mutex);
pthread_mutex_lock_t pthread_mutex_lock_f = NULL;
typedef int (*pthread_mutex_unlock_t)(pthread_mutex_t *mutex);
pthread_mutex_unlock_t pthread_mutex_unlock_f = NULL;
// implement
int pthread_mutex_lock(pthread_mutex_t *mutex) {
	pthread_t selfid = pthread_self();
	lock_before((uint64_t)selfid, (uint64_t)mutex);
	pthread_mutex_lock_f(mutex);
	lock_after((uint64_t)selfid, (uint64_t)mutex);
}
int pthread_mutex_unlock(pthread_mutex_t *mutex) {
	pthread_mutex_unlock_f(mutex);
	pthread_t selfid = pthread_self();
	unlock_after((uint64_t)selfid, (uint64_t)mutex);
}
// init
void init_hook(void) {
	if (!pthread_mutex_lock_f)
		pthread_mutex_lock_f = dlsym(RTLD_NEXT, "pthread_mutex_lock");
	if (!pthread_mutex_unlock_f)
		pthread_mutex_unlock_f = dlsym(RTLD_NEXT, "pthread_mutex_unlock");
}

以上是死鎖檢測的一個基本思路,將線程與資源及其關(guān)系抽象成有向圖,對圖進(jìn)行環(huán)回路檢測。而在使用死鎖檢測時,可以用一個獨立的線程監(jiān)控,不影響主程序性能。

到此這篇關(guān)于C++ 死鎖檢測基礎(chǔ)思路的文章就介紹到這了,更多相關(guān)C++ 死鎖檢測內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言實現(xiàn)會員管理系統(tǒng)

    C語言實現(xiàn)會員管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)會員管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語言實現(xiàn)的猴子偷桃之類算法

    C語言實現(xiàn)的猴子偷桃之類算法

    本文給大家分享的是前些日子去面試的時候的試題,哎,真是沒想到會出這么個題,好多年沒碰過C了。。。。分享給大家,小伙伴們過來參觀下吧。
    2015-03-03
  • C++實現(xiàn)簡單酒店管理系統(tǒng)

    C++實現(xiàn)簡單酒店管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)簡單酒店管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++實現(xiàn)百度坐標(biāo)(BD09)及GCJ02與WGS84之間的轉(zhuǎn)換

    C++實現(xiàn)百度坐標(biāo)(BD09)及GCJ02與WGS84之間的轉(zhuǎn)換

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)百度坐標(biāo)(BD09)及GCJ02與WGS84之間的轉(zhuǎn)換的方法,文中的示例代碼講解詳細(xì),希望對大家有所幫助
    2023-03-03
  • C語言通過二分查找實現(xiàn)猜數(shù)字游戲

    C語言通過二分查找實現(xiàn)猜數(shù)字游戲

    這篇文章主要為大家詳細(xì)介紹了在C語言中如何通過二分查找思想編寫一個簡單的猜數(shù)字游戲,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-02-02
  • C++中函數(shù)重載與引用的操作方法

    C++中函數(shù)重載與引用的操作方法

    C++中函數(shù)重載允許同名函數(shù)根據(jù)參數(shù)列表的不同而執(zhí)行不同的功能,這依賴于名字修飾或名字改編(Name Mangling)機(jī)制,而引用則是為變量創(chuàng)建一個別名,不會開辟新的內(nèi)存空間,本文介紹了C++中函數(shù)重載與引用的操作,感興趣的朋友一起看看吧
    2024-10-10
  • Matlab實現(xiàn)好看的配對箱線圖的繪制

    Matlab實現(xiàn)好看的配對箱線圖的繪制

    配對箱線圖,常見于配對樣本的數(shù)據(jù)分析中,它除了能夠表現(xiàn)兩組的整體差異,還能夠清晰地呈現(xiàn)單個樣本的前后改變。本文將用Matlab實現(xiàn)配對箱線圖的繪制,需要的可以參考一下
    2022-08-08
  • C++實現(xiàn)銀行排隊系統(tǒng)

    C++實現(xiàn)銀行排隊系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)銀行排隊系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • c語言同名標(biāo)靶點自動匹配算法實現(xiàn)實例代碼

    c語言同名標(biāo)靶點自動匹配算法實現(xiàn)實例代碼

    這篇文章主要介紹了c語言同名標(biāo)靶點自動匹配算法實現(xiàn)實例代碼,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • C++結(jié)構(gòu)體案例練習(xí)分享

    C++結(jié)構(gòu)體案例練習(xí)分享

    這篇文章主要和大家分享幾個C++?結(jié)構(gòu)體的案例練習(xí),幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下,希望能夠給你帶來幫助
    2022-04-04

最新評論

织金县| 双流县| 广水市| 达拉特旗| 麻阳| 抚宁县| 自贡市| 泉州市| 梅州市| 五指山市| 曲靖市| 墨竹工卡县| 禄丰县| 乌兰县| 丰城市| 甘肃省| 柞水县| 凤凰县| 平顶山市| 普兰店市| 乾安县| 榕江县| 磐安县| 肃宁县| 民乐县| 永兴县| 齐齐哈尔市| 策勒县| 怀来县| 左贡县| 莲花县| 宁化县| 江油市| 定陶县| 江达县| 大名县| 五河县| 海口市| 定兴县| 栾川县| 白银市|