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

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

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

一、理論部分

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

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

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

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

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

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

二、實(shí)現(xiàn)部分

我們?cè)诖藘H實(shí)現(xiàn)一個(gè)簡(jiǎn)易化的版本,由于理解死鎖檢測(cè)。

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

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

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

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

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

2. 核心邏輯

核心規(guī)則

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

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

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

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

3. 死鎖檢測(cè)算法

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

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");
}

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    c語言同名標(biāo)靶點(diǎn)自動(dòng)匹配算法實(shí)現(xiàn)實(shí)例代碼

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

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

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

最新評(píng)論

神木县| 四会市| 滦南县| 无锡市| 澄迈县| 富裕县| 巴彦淖尔市| 郯城县| 拜城县| 潞西市| 新竹市| 嵩明县| 泌阳县| 务川| 高要市| 枝江市| 青阳县| 南投市| 六安市| 格尔木市| 平安县| 万荣县| 华池县| 长沙市| 汉沽区| 渝北区| 凉山| 旅游| 榆树市| 如东县| 肥东县| 永福县| 改则县| 玛多县| 历史| 达日县| 府谷县| 太康县| 东阳市| 慈溪市| 南皮县|