C语言 pthread_cond_wait 好像死锁了,线程无法正常退出。。
本帖最后由 Cool_Breeze 于 2022-3-21 08:34 编辑源代码如下:
#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;
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, NULL, add, (void *)p0); break;
case 1: pthread_create(&pts, NULL, add, (void *)p1); break;
case 2: pthread_create(&pts, NULL, add, (void *)p2); break;
case 3: pthread_create(&pts, 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, 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
注释65行 我看到2点:1、 pthread_join 的问题。因为,你用是 for 中的递增条件去等线程退出。即线程必须要按照 PID 递增的顺序退出才能满足 for 循环的正常退出。 2、pthread_cond_broadcast 本来就会惊群,你的每个线程都是随机去执行的。
hunteraa 发表于 2022-3-20 20:11
我看到2点:1、 pthread_join 的问题。因为,你用是 for 中的递增条件去等线程退出。即线程必须要按照 PID...
线程应该会先一步退出,不知道为什么没有退出。 lswss 发表于 2022-3-20 19:54
注释65行
更不行了,到时候线程都被阻塞了,无法唤醒。 条件变量是需要配合线程锁使用的 hunteraa 发表于 2022-3-20 20:11
我看到2点:1、 pthread_join 的问题。因为,你用是 for 中的递增条件去等线程退出。即线程必须要按照 PID...
我可能理解错了,我去查查资料。 jamesAbc 发表于 2022-3-20 22:31
条件变量是需要配合线程锁使用的
嗯,需要把锁住的互斥量传递给pthread_cond_wait,感谢! 已解决:
#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;
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, NULL, add, (void *)p0); break;
case 1: pthread_create(&pts, NULL, add, (void *)p1); break;
case 2: pthread_create(&pts, NULL, add, (void *)p2); break;
case 3: pthread_create(&pts, 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, NULL);
}
pthread_mutex_destroy(&mut);
pthread_cond_destroy(&cod);
exit(0);
}
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
pthread_cond_wait有隐含操作:
1、阻塞等待之前,对处于锁状态的互斥量解锁
2、阻塞等待之后,对互斥量上锁
页:
[1]
2