【问题标题】:Conditional Variables with Posix ThreadsPosix 线程的条件变量
【发布时间】:2018-06-21 17:40:16
【问题描述】:

我想无限打印以下消息“多么美好的世界!” ,我从一开始就有3个线程来完成这项工作,第一个“What a”,第二个“Wonderful”和第三个“world”,(我在./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;
}

【问题讨论】:

    标签: c linux pthreads posix mutex


    【解决方案1】:

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

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

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

    【讨论】:

    • 您可以在堆栈上只拥有 3 个 id 变量,而不是在堆中分配每个变量。您还可以拥有 3 个不同的线程函数,这将使 id 变得不必要。不处理虚假唤醒。
    • @dbush 不起作用现在再次查看编辑后的代码,使用我的 main ,输出为空(运行时)
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2018-10-08
    • 2020-07-12
    • 2015-09-14
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多