死锁检测组件实现

简介: 死锁检测组件实现

       当线程多了之后,一部分线程做数据处理,一个线程做日志同步,还有做网络的线程及操作数据库的线程,当线程比较多的时候出现死锁的概率是很高的;

       使用htop去看cpu的使用情况,cpu占用率总是百分之百,这个时候就是进入了死锁的状态,一直在等一直在等;

       死锁的状态,是由于线程无法正常获取资源;如下1,2,3,4代表资源,A,B,C,D代表线程,开始1,2,3,4分别被A,B,C,D线程使用着,但是此时A又需要使用2,B需要使用4,C需要使用1,D需要使用3;而这些资源又已经被占用了无法竞争到,就产生了死锁;判断是否产生死锁就只要看是否有出现这样的环出现就可以了;

如何知道资源(比如pthread_mutex_lock(mutex))被哪个线程占用了呢?这个是不知道的,没办法判断的;

构建并打印死锁,通过hook机制,从而使得调用pthread_mutrex_lock,pthread_mutex_unlock时调用我们自己实现的对应函数;

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
typedef int (*pthread_mutex_lock_t)(pthread_mutex_t *mutex);
typedef int (*pthread_mutex_unlock_t)(pthread_mutex_t *mutex);
pthread_mutex_lock_t pthread_mutex_lock_f;
pthread_mutex_unlock_t pthread_mutex_unlock_f;
int pthread_mutex_lock(pthread_mutex_t *mutex) {
    pthread_t selfid = pthread_self();
    pthread_mutex_lock_f(mutex);
    printf("pthread_mutex_lock: %ld, %p\n", selfid, mutex);
}
int pthread_mutex_unlock(pthread_mutex_t *mutex) {
    pthread_t selfid = pthread_self();
    pthread_mutex_unlock_f(mutex);
    printf("pthread_mutex_unlock: %ld, %p\n", selfid, mutex);
}
void init_hook(void) {
    pthread_mutex_lock_f = dlsym(RTLD_NEXT, "pthread_mutex_lock");
    pthread_mutex_unlock_f = dlsym(RTLD_NEXT, "pthread_mutex_unlock");
}
#if 1
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex4 = PTHREAD_MUTEX_INITIALIZER;
void *thread_funcA(void *arg) {
    pthread_mutex_lock(&mutex1);
    sleep(1);
    pthread_mutex_lock(&mutex2);
    printf("thread_funcA\n");
    pthread_mutex_unlock(&mutex2);
    pthread_mutex_unlock(&mutex1);
}
void *thread_funcB(void *arg) {
    pthread_mutex_lock(&mutex2);
    sleep(1);
    pthread_mutex_lock(&mutex3);
    printf("thread_funcB\n");
    pthread_mutex_unlock(&mutex3);
    pthread_mutex_unlock(&mutex2);
}
void *thread_funcC(void *arg) {
    pthread_mutex_lock(&mutex3);
    sleep(1);
    pthread_mutex_lock(&mutex4);
    printf("thread_funcC\n");
    pthread_mutex_unlock(&mutex4);
    pthread_mutex_unlock(&mutex3);
}
void *thread_funcD(void *arg) {
    pthread_mutex_lock(&mutex4);
    sleep(1);
    pthread_mutex_lock(&mutex1);
    printf("thread_funcD\n");
    pthread_mutex_unlock(&mutex1);
    pthread_mutex_unlock(&mutex4);
}
int main() {
    init_hook();
    pthread_t tida, tidb, tidc, tidd;
    pthread_create(&tida, NULL, thread_funcA, NULL);
    pthread_create(&tidb, NULL, thread_funcB, NULL);
    pthread_create(&tidc, NULL, thread_funcC, NULL);
    pthread_create(&tidd, NULL, thread_funcD, NULL);
    pthread_join(tida, NULL);
    pthread_join(tidb, NULL);
    pthread_join(tidc, NULL);
    pthread_join(tidd, NULL);
    return 0;
}
#endif

       死锁检测,可以通过构建有向图判断是否有环来检测;图的构建方式,可以通过矩阵和邻接表;以邻接表,若线程1申请线程2的资源,而该资源又被线程2占用着,我们就将线程1的next指针指向线程2,表示线程1生成的资源已经被线程2占用了;

       新增线程并在线程中有调用pthread_mutex_lock的时候就相当于在图上新增节点,新增边则是在当调用pthread_mutex_lock发现资源被其他线程占用的时候;

目录
打赏
0
0
0
0
0
分享
相关文章
|
9月前
|
死锁检测组件
死锁检测组件
52 0
死锁原因及死锁检测组件的实现
死锁原因及死锁检测组件的实现
146 0
线程死锁检测组件逻辑与源码
线程死锁检测组件逻辑与源码
92 2
死锁检测组件原理及代码实现
死锁检测组件原理及代码实现
第十六章——处理锁、阻塞和死锁(1)——确定长时间运行的事务
原文: 第十六章——处理锁、阻塞和死锁(1)——确定长时间运行的事务 前言: 事务是OLTP系统中的主要部分。它管理数据一致性和数据并发问题,当多个资源同时被读取或者修改相同数据时,SQLServer会通过锁定机制来确保数据库中的数据总是处于一个有效状态。
1293 0
什么是可中断锁?有什么用?怎么实现?(4)
什么是可中断锁?有什么用?怎么实现?(4)
243 0
什么是可中断锁?有什么用?怎么实现?(3)
什么是可中断锁?有什么用?怎么实现?(3)
107 0
什么是可中断锁?有什么用?怎么实现?(3)

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等