1

今天学习pthread,我写了一个关于生产者和消费者问题的玩具例子。但是我发现当我将pthread_cond_signal放入循环或不循环时,程序的动作是不同的。这是原始代码。

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

int good_count = 0;
int total = 0;
pthread_mutex_t mt;
pthread_cond_t cv;
volatile int producer_wait = 1;

void* produce()
{
    pthread_mutex_lock(&mt);
    printf("Producer Wait;\n");
    producer_wait = 1;
    pthread_cond_wait(&cv, &mt);
    producer_wait = 0;
    printf("Received a signal\n");
    pthread_mutex_unlock(&mt);

    pthread_exit(NULL);
}

void* consume()
{
    pthread_mutex_lock(&mt);
    while(producer_wait)
    {
        pthread_cond_signal(&cv);
        sleep(1);
    }
    //pthread_cond_signal(&cv);
    pthread_mutex_unlock(&mt);

    pthread_exit(NULL);
}

int main()
{
    pthread_t threads[2];
    pthread_attr_t attr;

    /*initialize mutex and cond */
    pthread_mutex_init(&mt, NULL);
    pthread_cond_init(&cv, NULL);

    /*initialize thread attribute*/
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    pthread_create(&threads[0], &attr, produce, NULL);
    pthread_create(&threads[1], &attr, consume, NULL);

    int i;
    for (i = 0; i < 2; i++) {
        pthread_join(threads[i], NULL);
    }

    pthread_attr_destroy(&attr);
    pthread_mutex_destroy(&mt);
    pthread_cond_destroy(&cv);
    pthread_exit(NULL);
}

生产者线程在pthread_cond_wait(&cv, &mt)中阻塞,消费者线程在while循环中调用pthread_cond_signal(&cv)不生效。但是如果我这样修改consume()函数代码,它就会生效。

void* consume()
{
    pthread_mutex_lock(&mt);

    /*while(producer_wait)
    {
        pthread_cond_signal(&cv);
        sleep(1);
    }*/
    pthread_cond_signal(&cv);
    pthread_mutex_unlock(&mt);

    pthread_exit(NULL);
}

我很困惑,希望得到答案!

我修改了consume函数,将pthread_mutex_lock(&mt)和pthread_mutex_unlock(&mt)移到while循环中,注释sleep(1),消费者可以释放互斥锁,这样生产者线程就可以接收到信号了。但是如果我取消注释 sleep(1),生产者线程无法接收信号。为什么?

void* consume()
{
    while(producer_wait)
    {
        pthread_mutex_lock(&mt);
        pthread_cond_signal(&cv);
        //sleep(1);
        pthread_mutex_unlock(&mt);
    }
    pthread_exit(NULL);
}

消费者线程

4

1 回答 1

1

有了循环,你的消费者永远不会释放互斥锁,生产者需要互斥锁继续,所以死锁

于 2013-05-29T14:16:49.600 回答