死锁检测实现

本文介绍了如何在多进程、多线程环境中检测死锁问题。通过构建有向图来表示资源获取关系,利用深度优先搜索算法进行图遍历,检测资源环路,从而判断是否存在死锁。文章详细讲解了数据结构的设计,图的操作,包括创建节点、添加边,以及启动检测线程和利用钩子hook方法在加锁、解锁时进行死锁检测。提供了具体的C/C++实现策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、背景

  在工作项目使用多进程、多线程过程中,因争夺资源而造成一种资源竞态,所以需加锁处理。如下图所示,线程A想获取线程B的锁,线程B想获取线程C的锁,线程 C 想获取线程D的锁, 线程D想获取线程A的锁,从而构建了一个资源获取环,当进程或者线程申请的锁处于相互交叉锁住的情况,就会出现死锁,它们将无法继续运行。

  死锁的存在是因为有资源获取环的存在,所以只要能检测出资源获取环,就等同于检测出死锁的存在。

二、原理

  在不改变项目源代码的情况下,采用图算法来检测环的存在,使用有向图来存储;如线程A获取线程B已占用的锁(表示线程B获取锁成功),则为线程A指向线程B;启动一个线程定时对图进行检测是否有环的存在。

   (1)数据结构

//数据/点
struct node{

    uint64 thread_id;//线程ID
    uint64 lock_id;//锁ID
    int degress;
};

//数据和数据结构分开
struct vertex{

    struct node *d;
    struct vertex *next;
};

struct graph{

    struct vertex list[THREAD_MAX];//存储图的所有节点
    int num;//已经使用了多少个

    struct node locklist[THREAD_MAX];
    int lockidx;
    
    pthread_mutex_t mutex;//预留:线程安全考虑,在对图修改时加锁
};

   (2)图的操作

    a.创建图节点

//创建图节点
struct vertex *create_vertex(struct node *d){

    struct vertex *tex =  (struct vertex*)calloc(1,sizeof(struct vertex));
    if(tex == NULL) return NULL;

    tex->d = d;
    tex->next = NULL;
    return tex;
}

       b.查找节点

//查找节点,是否存在
int search_vertex(struct node *d){

    int i;
    for (i = 0; i < tg->num; i++)
    {
        if (tg->list[i].d->thread_id == d->thread_id)
        {
            return i;
        }
    }

       c.添加节点

//添加节点,只是把添加的节点放到list中,还没有确定各节点间的指向,必须通过add_edge添加边来确定
void add_vertex(struct node *d){

    if (search_vertex(d) == -1)
    {
        tg->list[tg->num].d = d;//添加到list中
        tg->list[tg->num].next = NULL;

        tg->num++;//节点数累加
    }
}

       d.添加边,指定方向

//添加边,指定方向,谁指向谁
void add_edge(struct no
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值