//dfs深度遍历
int dfs(int idx){
struct vertex *v = &tg->list[idx];
if(visited[idx] == 1){//有环
path[k++] = idx;
print_deadlock();
deadlock = 1;
return 0;
}
visited[idx] =1;//被遍历到了,赋值为1,保证同一个节点只能遍历一次
path[k++] = idx;
while(v->next !=NULL){
dfs(search_vertex(v->next->d));
k--;
v = v->next;
}
return 1;
}
//遍历图,任意从图的一个节点出发,对每一个节点进行dfs遍历
int search_for_cycle(int idx){
struct vertex *v = &tg->list[idx];
visited[idx] = 1;
k = 0;
path[k++] = idx;
while(v->next != NULL){
int i = 0;
for (; i < tg->num; i++)
{
if(i == idx){
continue;
}
visited[i] = 0;
}
for(i = 1; i <= THREAD_MAX; i++){
path[i] = -1;
}
k = 1;
dfs(search_vertex(v->next->d));
v = v->next;
}
}
(4)启动检测
C++后台开发架构师免费学习地址:C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂
另外还整理一些C++后台开发架构师 相关学习资料,面试题,教学视频,以及学习路线图,免费分享有需要的可以自行添加点击 正在跳转 群文件共享

启动线程定时检测图是否有环,代码如下。
//从第0个节点开始dfs
void check_dead_lock(){
int i = 0;
deadlock = 0;
for(;i < tg->num; i++){
if(deadlock == 1) break;
search_for_cycle(i);
}
if(deadlock == 0){
printf("no deadlock
");
}
}
//检测锁线程func
static void *thread_func(void *args){
while(1){
sleep(5);
check_dead_lock();
}
}
//启动检测锁线程
void start_check(){
tg = (struct graph*)malloc(sizeof(struct graph));
tg->num = 0;
tg->lockidx = 0;
pthread_t tid;
pthread_create(&tid,NULL,thread_func,NULL);
}
(5)钩子hook
为了不改变项目原代码,使用hook在应用程序调用系统加锁、解锁API时进行劫持,使其实际调用的是应用程序定义的加锁、解锁API;再进行加锁、解锁前,我们先去理解3个状态,加锁前、加锁后、解锁后,即:lock_before、lock_after、unlock_after,通过这三个函数与图构建起来,具体实现如下。
//1.没有被其他线程占用,不用处理
//2.有被其它线程占用,就要把边构建起来
// 添加边
void lock_before(uint64 thread_id, uint64 lockid){
int idx = 0;
for(;idx < tg->lockidx;idx++){
if(tg->locklist[idx].lock_id == lockid){
struct node from;
from.thread_id = thread_id;
add_vertex(&from);
struct node to;
to.thread_id = tg->locklist[idx].thread_id;
tg->locklist[idx].degress++;
add_vertex(&to);
if(!verifty_edge(&from, &to)){
add_edge(&from, &to);//添加边
}
}
}
}
//1.没有被其它线程占用
//先加入一个节点add_edge
//2.有被占用
//是进不来lock_after的
//
//等unlock_after 释放后
// mtx没有主人
void lock_after(uint64 threadid, uint64 lockid) {
int idx = 0;
if(-1 == (idx = search_lock(lockid))){
int eidx = search_empty_lock();
tg->locklist[eidx].thread_id = threadid;
tg->locklist[eidx].lock_id = lockid;
inc(&tg->lockidx, 1);
}else{
struct node from;
from.thread_id = threadid;
struct node to;
to.thread_id = tg->locklist[idx].thread_id;
tg->locklist[idx].degress--;
if(verifty_edge(&from, &to)){
remove_edge(&from, &to);//不在死锁检测的圈里面了,所以删除边
}
tg->locklist[idx].thread_id = threadid;
}
}
void unlock_after(uint64 threadid, uint64 lockid) {
int idx = search_lock(lockid);
if(tg->locklist[idx].degress == 0){
tg->locklist[idx].thread_id = 0;
tg->locklist[idx].lock_id = 0;
}
}