首页 文章

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

提问于
浏览
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;
}

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

任何帮助赞赏 .

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 .

相关问题