消费者 - 生产者有pthreads的赛车条件

问题描述 投票:1回答:1

我正在使用ubuntu 16.04中的pthreads在具有2个处理器的虚拟机上实现消费者 - 生产者问题。我们有n个生产者和一个消费者,他们通过缓冲区从每个生产者那里读取数据。每个生产者都有自己的缓冲区。问题是,在某些时候我的代码死锁,无法找出原因。可能是我搞乱了条件变量和互斥锁。

typedef struct
{
    Student*        buf;         // the buffer
    int             producer_id;
    size_t          len;         // number of items in the buffer
    pthread_mutex_t mutex;       // needed to add/remove data from the buffer
    pthread_cond_t  can_produce; // signaled when items are removed
    pthread_cond_t  can_consume; // signaled when items are added
    bool            isDone;
} buffer_t;

这是用于消费者和生产者之间数据传输的缓冲结构。

void* producer(void *param)
{
    buffer_t* buffer = (buffer_t*)param;
    char*     line   = NULL;
    size_t    len    = 0;
    ssize_t   read;
    FILE*     inFileReader;

    inFileReader = fopen(inFile, "r");
    while ((read = getline(&line, &len, inFileReader)) != -1)
    {
        pthread_mutex_lock(&buffer->mutex);
        if (buffer->len == BUFFER_SIZE)
        {// buffer full wait
            pthread_cond_wait(&buffer->can_produce, &buffer->mutex);
        }

        //buffer filled up with the read data from the file.
        if (conditionValid)
        {
            //add item to buffer
            ++buffer->len;
        }

        pthread_cond_signal(&buffer->can_consume);
        pthread_mutex_unlock(&buffer->mutex);
    }

    fclose(inFileReader);
    buffer->isDone = true;
    pthread_exit(NULL);

    return NULL;
}

这是生产者,从给定的文件中读取数据并填充缓冲区,当文件结束时,生产者线程将退出。

void* consumer(void *param)
{
    buffer_t* buffer_array = (buffer_t*)param;
    sleep(rand() % 3);
    int i =0;

    while (!buffer_array[i%N].isDone || buffer_array[i%N].len != 0)
    {
        pthread_mutex_lock(&buffer_array[i%N].mutex);

        if (buffer_array[i%N].len == 0)
        {
            pthread_cond_wait(&buffer_array[i%N].can_consume, 
                              &buffer_array[i%N].mutex);
        }

        while (buffer_array[i%N].len != 0)
        {
            buffer_array[i%N].len--;
            //read from buffer
        }

        pthread_cond_signal(&buffer_array[i%N].can_produce);
        pthread_mutex_unlock(&buffer_array[i%N].mutex);
        i++;
    }

    fclose(outFileWriter);
    pthread_exit(NULL);

    return NULL;
} 

使用者从每个生成器读取缓冲区,并且当所有完成的使用者退出循环并终止线程时。

任何帮助赞赏。

c multithreading pthreads producer-consumer
1个回答
0
投票

死锁是因为生成器只用一个标志集完成读取:

buffer->isDone = true;

那么,如果那时消费者正在等待生产者1的条件:

    // say i == 1
    if (buffer_array[i%N].len == 0)
    {
        pthread_cond_wait(&buffer_array[i%N].can_consume, 
                          &buffer_array[i%N].mutex);
    }

这种情况永远不会发生。消费者没有进步,所以一切都只是摊位。

解决方案可能是在设置isDone后触发can_consume

© www.soinside.com 2019 - 2024. All rights reserved.