Cool_Breeze 发表于 2022-3-20 17:29

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

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

lswss 发表于 2022-3-20 19:54
注释65行

更不行了,到时候线程都被阻塞了,无法唤醒。

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

已解决:


#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

ZheCi 发表于 2022-3-21 09:25

pthread_cond_wait有隐含操作:
1、阻塞等待之前,对处于锁状态的互斥量解锁
2、阻塞等待之后,对互斥量上锁
页: [1] 2
查看完整版本: C语言 pthread_cond_wait 好像死锁了,线程无法正常退出。。