Posix 线程的条件变量

标签 c linux pthreads posix mutex

我想无限打印下面的消息“What a wonderful world!” ,我从一开始就有 3 个线程来完成这项工作,第一个“What a”,第二个“Wonderful”和第三个“world”,(我在 ./a.out 3 中作为参数给出),问题在下面的代码是这样显示的消息:What a wonderful what a wonderful the World is missing. I think Something is bad with the conditional variables, any suggestions?

int p;
void *disp(void *arg);
pthread_mutex_t muta,mutb,mutc;
pthread_cond_t condition_cond= PTHREAD_COND_INITIALIZER;

void *disp(void *arg)
{

    int id=*(int*)arg;
    free(arg);  
    arg=0;

    pthread_mutex_lock(&muta);
    while (id==0)
    {   
        pthread_cond_wait (&condition_cond,&muta);  
    }
    printf("What a");
    pthread_mutex_unlock(&muta);
    pthread_mutex_lock(&mutb);
    while (id==1)
    {               
        pthread_cond_wait (&condition_cond,&mutb);
    }
    printf(" Wonderful");
    pthread_mutex_unlock(&mutb); 
    pthread_mutex_lock(&mutc);
    while(id==2) 
    {   
        pthread_cond_wait (&condition_cond,&mutc);

    }
    printf(" World!\n");
    pthread_mutex_unlock(&mutc); 
    return NULL;
} 

编辑:根据 dbush 的回答更新代码:

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>

int p;
void *disp(void *arg);
pthread_mutex_t mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond1= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond3= PTHREAD_COND_INITIALIZER;

void *disp(void *arg)
{
    int id=*(int*)arg;
    free(arg);  
    arg=0;

    pthread_mutex_lock(&mut);
    while(1)
    {
            if (id==0)
            {
                pthread_cond_wait (&cond1,&mut);
                printf("What a ");
                pthread_cond_signal (&cond2);

            }
            else if(id==1)
            {
                pthread_cond_wait (&cond2,&mut);
                printf(" wonderful ");
                pthread_cond_signal (&cond3);
            }
            else if(id==2)
            {
                pthread_cond_wait (&cond3,&mut);
                printf(" world!\n ");
                pthread_cond_signal (&cond1);
            }

    }

    return NULL;
} 



int main (int argc,char *argv[])
{
    int i;
    pthread_t *tid;
    if(argc!=2)
     {
        printf("Provide number of threads.\n");
         exit(1);
     }

     p=atoi(argv[1]);
     tid=(pthread_t *) malloc (p*sizeof(pthread_t));

     if (tid==NULL)
     {
        printf("Could not allocate memory.\n");
        exit(1);
     }

    for (i=0;i<p;++i)
    {
        int *a;
        a=malloc(sizeof(int));                  //pointer to pass
        *a=i;
        pthread_create(&tid[i],NULL,disp,a);
    }

    pthread_cond_signal(&cond1);

    for (i=0;i<p;++i)
        pthread_join(tid[i],NULL);

    return 0;
}

最佳答案

您已经颠倒了互斥量和条件变量的用法。您需要一个互斥量来控制所有三个线程,以及三个条件变量(每个线程一个)。

每个线程完成其工作后,应使用目标线程的条件变量向下一个线程发出信号。此外,main 函数需要向第一个线程发出信号以开始工作。您会希望它休眠一小段时间,以便所有线程都有时间启动。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

void *disp(void *arg);
pthread_mutex_t mux = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond1= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond3= PTHREAD_COND_INITIALIZER;

void *disp(void *arg)
{

    int id=*(int*)arg;
    free(arg);
    arg=0;

    pthread_mutex_lock(&mux);
    while (1) {
        if (id==0) {
            pthread_cond_wait (&cond1,&mux);
            printf("What a");
            pthread_cond_signal(&cond2);
        } else if (id == 1) {
            pthread_cond_wait (&cond2,&mux);
            printf(" Wonderful");
            pthread_cond_signal(&cond3);
        } else if (id == 2) {
            pthread_cond_wait (&cond3,&mux);
            printf(" World!\n");
            pthread_cond_signal(&cond1);
        }
    }
    return NULL;
}
int main()
{
    pthread_t t1, t2, t3;

    int *id = malloc(sizeof(int));
    *id=0;
    pthread_create(&t1, NULL, disp, id);

    id = malloc(sizeof(int));
    *id=1;
    pthread_create(&t2, NULL, disp, id);

    id = malloc(sizeof(int));
    *id=2;
    pthread_create(&t3, NULL, disp, id);

    sleep(1);
    pthread_cond_signal(&cond1);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    pthread_join(t3, NULL);

    return 0;
}

关于Posix 线程的条件变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50974614/

相关文章:

c - 从 XML C 字符串表示中提取值节点

c - 从文件读取时程序崩溃

c - 使用 TCP 套接字发送/读取,字节大小异常

linux - 更改 while 循环内的变量

php - PHP 未完全检索 Shell 输出!

C 中取消线程

c++ - MySQL/C++ 连接器 mysql_real_escape_string 函数

c - pthread_create() 中带有可变参数的函数?

c++ - Linux c++ 中的 shmget() 函数

linux - bash 不会分配变量