吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1801|回复: 10
收起左侧

[已解决] C语言 pthread_cond_wait 好像死锁了,线程无法正常退出。。

[复制链接]
Cool_Breeze 发表于 2022-3-20 17:29
本帖最后由 Cool_Breeze 于 2022-3-21 08:34 编辑

源代码如下:
[C] 纯文本查看 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>


static int count;
static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cod = PTHREAD_COND_INITIALIZER;
static int nu;

void *add(void *pname){


	while (1){

		pthread_cond_wait(&cod, &mut);
		char *pname1 = pname;
		printf("pid_or_name:%s count=%d\n", pname1, count); 
		
		if (count > 10) {
			printf("exit %s\n", pname1);
			pthread_exit(NULL);

		}
		count ++;
	}
	return NULL;

}




int main(void){


	int n = 4;

	int i=0;
	

	pthread_t pts[4];
	char *p0 = "p0";
	char *p1 = "p1";
	char *p2 = "p2";
	char *p3 = "p3";
	for (i=0; i<n; i++){


		switch (i){

			case 0: pthread_create(&pts[i], NULL, add, (void *)p0); break;
			case 1: pthread_create(&pts[i], NULL, add, (void *)p1); break;
			case 2: pthread_create(&pts[i], NULL, add, (void *)p2); break;
			case 3: pthread_create(&pts[i], NULL, add, (void *)p3); break;
			default: break;
				
		}	

	}	

	for (i=0; i<5; i++){

		sleep(1);
		pthread_cond_broadcast(&cod);
	}

	for (i=0; i<n; i++){
		printf("join:%d\n", i);
		pthread_join(pts[i], NULL);

	}

	pthread_mutex_destroy(&mut);
	pthread_cond_destroy(&cod);

	exit(0);

}



运行结果如下:
pid_or_name:p0 count=0
pid_or_name:p1 count=1
pid_or_name:p3 count=2
pid_or_name:p2 count=3
pid_or_name:p3 count=4
pid_or_name:p2 count=5
pid_or_name:p0 count=6
pid_or_name:p1 count=7
pid_or_name:p3 count=8
pid_or_name:p2 count=9
pid_or_name:p0 count=10
pid_or_name:p1 count=11
exit p1
join:0

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

lswss 发表于 2022-3-20 19:54
注释65行
hunteraa 发表于 2022-3-20 20:11
我看到2点:1、 pthread_join 的问题。因为,你用是 for 中的递增条件去等线程退出。即线程必须要按照 PID 递增的顺序退出才能满足 for 循环的正常退出。 2、pthread_cond_broadcast 本来就会惊群,你的每个线程都是随机去执行的。
 楼主| Cool_Breeze 发表于 2022-3-20 21:05
hunteraa 发表于 2022-3-20 20:11
我看到2点:1、 pthread_join 的问题。因为,你用是 for 中的递增条件去等线程退出。即线程必须要按照 PID  ...

线程应该会先一步退出,不知道为什么没有退出。
 楼主| Cool_Breeze 发表于 2022-3-20 21:06

更不行了,到时候线程都被阻塞了,无法唤醒。
jamesAbc 发表于 2022-3-20 22:31
条件变量是需要配合线程锁使用的
 楼主| Cool_Breeze 发表于 2022-3-20 22:31
hunteraa 发表于 2022-3-20 20:11
我看到2点:1、 pthread_join 的问题。因为,你用是 for 中的递增条件去等线程退出。即线程必须要按照 PID  ...

我可能理解错了,我去查查资料。
 楼主| Cool_Breeze 发表于 2022-3-21 08:34
jamesAbc 发表于 2022-3-20 22:31
条件变量是需要配合线程锁使用的

嗯,需要把锁住的互斥量传递给pthread_cond_wait,感谢!
 楼主| Cool_Breeze 发表于 2022-3-21 09:04
已解决:

[C] 纯文本查看 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>


static int count;
static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cod = PTHREAD_COND_INITIALIZER;
static int nu;

void *add(void *pname){


    while (1){

        pthread_mutex_lock(&mut);
        while (nu == 0)
            pthread_cond_wait(&cod, &mut);
        char *pname1 = pname;
        printf("pid_or_name:%s count=%d\n", pname1, count);
        pthread_mutex_unlock(&mut);
        if (count > 10) {
            printf("exit %s\n", pname1);
            pthread_exit(NULL);

        }
        count ++;
        sleep(1); // debug not used
    }
    return NULL;

}




int main(void){


    int n = 4;

    int i=0;


    pthread_t pts[4];
    char *p0 = "p0";
    char *p1 = "p1";
    char *p2 = "p2";
    char *p3 = "p3";
    for (i=0; i<n; i++){


        switch (i){

            case 0: pthread_create(&pts[i], NULL, add, (void *)p0); break;
            case 1: pthread_create(&pts[i], NULL, add, (void *)p1); break;
            case 2: pthread_create(&pts[i], NULL, add, (void *)p2); break;
            case 3: pthread_create(&pts[i], NULL, add, (void *)p3); break;
            default: break;

        }

    }


    for (i=0; i<5; i++){

        printf("wait nu = 1\n");
        nu = 1;
        pthread_cond_broadcast(&cod);
        sleep(1);

        printf("wait nu = 0\n");
        nu = 0;
        sleep(1);
    }

    for (i=0; i<n; i++){
        printf("join:%d\n", i);
        pthread_join(pts[i], NULL);

    }

    pthread_mutex_destroy(&mut);
    pthread_cond_destroy(&cod);

    exit(0);

}


[C] 纯文本查看 复制代码
wait nu = 1
pid_or_name:p1 count=0
pid_or_name:p0 count=1
pid_or_name:p2 count=2
pid_or_name:p3 count=3
wait nu = 0
wait nu = 1
pid_or_name:p2 count=4
pid_or_name:p0 count=5
pid_or_name:p1 count=6
pid_or_name:p3 count=7
wait nu = 0
wait nu = 1
pid_or_name:p1 count=8
pid_or_name:p2 count=9
pid_or_name:p0 count=10
pid_or_name:p3 count=11
exit p3
pid_or_name:p1 count=11
exit p1
wait nu = 0
wait nu = 1
pid_or_name:p0 count=11
exit p0
pid_or_name:p2 count=11
exit p2
wait nu = 0
wait nu = 1
wait nu = 0
join:0
join:1
join:2
join:3
ZheCi 发表于 2022-3-21 09:25
pthread_cond_wait有隐含操作:
1、阻塞等待之前,对处于锁状态的互斥量解锁
2、阻塞等待之后,对互斥量上锁

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
Cool_Breeze + 1 + 1 谢谢@Thanks!

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 14:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表