这个生产者-消费者实现中是否存在竞争条件? [英] Are there race conditions in this producer-consumer implementation?
问题描述
在操作系统概念(Silberschatz,第 9 版)的第 3.4.1 节中,作者提出了生产者-消费者问题,并给出了以下使用循环缓冲区的实现(第 125、126 页).
In section 3.4.1 of Operating System Concepts (Silberschatz, 9th edition), the authors present the producer-consumer problem and give the following implementation that uses a circular buffer (page 125, 126).
//Shared variables
#define BUFFER SIZE 10
struct Item;
Item buffer[BUFFER SIZE];
int in = 0, out = 0;
//buffer is empty when in == out
//buffer is full when (in + 1) % BUFFER SIZE == out
//Producer
while (true)
{
Item next_produced = /*produce item here*/;
while (((in + 1) % BUFFER SIZE) == out) ; //do nothing
buffer[in] = next_produced;
in = (in + 1) % BUFFER SIZE;
}
//Consumer
while (true)
{
while (in == out) ; //do nothing
Item next_consumed = buffer[out];
out = (out + 1) % BUFFER SIZE;
//consume the item in next_consumed here
}
书中说:
这个插图没有解决的一个问题是关于生产者进程和消费者进程都试图并发访问共享缓冲区.
One issue this illustration does not address concerns the situation in which both the producer process and the consumer process attempt to access the shared buffer concurrently.
我没有看到生产者和消费者同时访问相同缓冲区元素的情况.
I do not see a situation where the producer and consumer would access the same buffer element simultaneously.
我的问题是:如果生产者和消费者在两个线程中运行,那么这个实现中是否存在竞争条件或其他同步问题?
My question is: if the producer and consumer ran in two threads, are there race conditions or other synchronization problems in this implementation?
推荐答案
有很多可能性
最明显的:如果有 2 个生产者生产数据.假设缓冲区中只有 1 个可用空间,两个生产者线程都可以通过
while (in + 1) % BUFFER SIZE) == out
并尝试放入缓冲区.这可能会导致缓冲区损坏或数据丢失
The most obvious: if there are 2 producer producing data. Assuming there is only 1 free space in the buffer, both producer thread can get pass the
while (in + 1) % BUFFER SIZE) == out
and try to put to the buffer. This can lead to corrupted buffer or missing data
即使只有 1 个消费者和 1 个生产者,仍然存在一些不太明显的问题.例如,编译器可能会重新排列行
Even there is only 1 consumer and 1 producer, there are still some less obvious problem. For example, compiler may rearrange the lines
buffer[in] = next_produced;
in = (in + 1) % BUFFER SIZE;
使in
的更新早于buffer
的更新,导致消费者访问未初始化的数据.
to make the update of in
happen earlier than update of buffer
, which cause the consumer accessing uninitialized data.
这篇关于这个生产者-消费者实现中是否存在竞争条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!