2

我正在尝试在有界缓冲区中使用生产者/消费者线程。缓冲区长度为 5。我有 1 个互斥体和 2 个信号量,从缓冲区大小开始是空的,从 0 开始是满的。

当我在最后没有 sleep() 的情况下运行我的代码时,它会不断产生直到缓冲区完全填满,消耗直到它为空,所以输出如下所示:

Placed 1 in the buffer at position 0.
Placed 2 in the buffer at position 1.
Placed 3 in the buffer at position 2.
Placed 4 in the buffer at position 3.
Placed 5 in the buffer at position 4.
The buffer now contains 0 at position 0.
The buffer now contains 0 at position 1.
The buffer now contains 0 at position 2.
The buffer now contains 0 at position 3.
The buffer now contains 0 at position 4.

但是,当我最后使用 sleep() 运行时,它会打印出:

Placed 1 in the buffer at position 0.
The buffer now contains 0 at position 0.

然后它似乎被锁定了,但我不确定为什么不管是否有睡眠,它的行为方式都是如此。有什么建议么?我的主要方法基本上只是做了一些声明,然后创建 1 个线程来生产和 1 个线程来消费,这些方法如下。

void *producer()
{
        int k = 0; //producer index
        while (1)
        {
                sem_wait(&empty);
                pthread_mutex_lock(&mutex);
                buffer[k] = k+1;
                sem_post(&full);
                pthread_mutex_unlock(&mutex);
                printf("Placed %d in the buffer at position %d.\n", buffer[k], k);
                k = (k + 1) % BUFFER_SIZE;
                sleep(rand() * 10);
        }
}

void *consumer()
{
        int j = 0;   //consumer index
        while(1)
        {
                sem_wait(&full);
                pthread_mutex_lock(&mutex);
                buffer[j] = 0;
                sem_post(&empty);
                pthread_mutex_unlock(&mutex);
                printf("The buffer now contains %d at position %d.\n", buffer[j], j);
                j = (j + 1) % BUFFER_SIZE;
                sleep(rand() * 10);

        }
}
4

4 回答 4

3

参数 tosleep()是休眠的秒数。 返回一个介于 0 和(通常为 32767 或 2 31rand() -1)之间的整数,当您将其乘以 10 时,您的睡眠时间非常长。你没有死锁,只是睡了很长时间。RAND_MAX

于 2010-11-05T19:18:41.420 回答
2

我不知道这是否是你死锁的原因,但你必须小心sem_t它们会受到中断的函数,特别是由于 IO 和类似的事情。

永远不要忽略系统函数的返回。在这里,您必须检查退货,然后errno检查EINTR.

然后,我不知道您是否被迫使用sem_t,但我认为这里更自然的是使用pthread_cond_t. 无论如何,你有一个互斥锁,所以这更容易适应。pthread_cond_t因为pthread_mutex_t功能永远不会中断。

于 2010-11-05T19:17:56.297 回答
1

Do you have any idea why when I don't include sleep it always produces and consumes in blocks instead of every other?

这可能是因为给每个线程约 30 毫秒的时间片足以让生产者在上下文切换有机会发生之前生产所有内容。

于 2010-11-05T19:53:58.090 回答
0

我假设您的两个线程具有相同的优先级?这是在具有多个核心的机器上,还是只有一个?仅发出信号量不会抢占您当前的线程,因此预计当前线程将继续运行,直到其切片到期。

另外,我肯定会在发出互斥锁之前解锁互斥锁。

于 2010-11-05T19:32:14.927 回答