在《操作系统概念》(Silberschatz,第 9 版)的 3.4.1 节中,作者提出了生产者-消费者问题,并给出了以下使用循环缓冲区的实现(第 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
}
书上说:
本图没有解决的一个问题涉及以下情况:
生产者进程和消费者进程都试图
同时访问共享缓冲区。
我没有看到生产者和消费者会访问的情况same同时缓冲元件。
我的问题是:如果生产者和消费者在两个线程中运行,那么此实现中是否存在竞争条件或其他同步问题?
有很多可能性
最明显的是:如果有 2 个生产者生产数据。假设缓冲区中只有 1 个可用空间,两个生产者线程都可以通过while (in + 1) % BUFFER SIZE) == out
并尝试放入缓冲区。这可能会导致缓冲区损坏或数据丢失
-
即使只有 1 个消费者和 1 个生产者,仍然存在一些不太明显的问题。例如,编译器可能会重新排列行
buffer[in] = next_produced;
in = (in + 1) % BUFFER SIZE;
进行更新in
发生早于更新buffer
,这会导致消费者访问未初始化的数据。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)