Posix线程的条件变量

时间:2018-06-21 17:40:17

标签: c linux pthreads mutex

我想将以下消息“无限美好!”打印为无限大。 ,从头开始,我有3个线程来完成这项工作,第一个是“什么一个,第二个是“精彩”,第三个是“世界”,(我在./a.out 3中作为参数给出),问题出在下面的代码是这样显示的消息:What a wonderful what a wonderful World丢失了。我认为条件变量有些不好,有什么建议吗?

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;
}

1 个答案:

答案 0 :(得分: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;
}