首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在这个生产者-消费者的实施中有种族条件吗?

在这个生产者-消费者的实施中有种族条件吗?
EN

Stack Overflow用户
提问于 2016-01-15 06:11:59
回答 2查看 1.1K关注 0票数 3

在操作系统概念3.4.1节(Silberschatz,第9版)中,作者介绍了生产者-消费者问题,并给出了以下使用循环缓冲区的实现(第125、126页)。

代码语言:javascript
复制
//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
}

书上说:

此示例没有解决的一个问题涉及生产者进程和使用者进程同时尝试访问共享缓冲区的情况。

我不认为生产者和使用者会同时访问相同的缓冲区元素。

我的问题是:如果生产者和使用者在两个线程中运行,这个实现中是否存在竞争条件或其他同步问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-15 06:57:46

有很多可能性

  1. 最明显的是:如果有两个生产者生产数据。假设缓冲区中只有一个空闲空间,两个生产者线程都可以传递while (in + 1) % BUFFER SIZE) == out并尝试放入缓冲区。这可能导致缓冲区损坏或数据丢失。
  2. 即使只有一个消费者和一个生产者,仍然存在一些不那么明显的问题。例如,编译器可能会重新排列行。 bufferin = next_produced;in = (in + 1) %缓冲区大小; 使in的更新比buffer的更新更早,这会导致使用者访问未初始化的数据。
票数 2
EN

Stack Overflow用户

发布于 2016-01-15 08:38:31

不能保证在修改buffer[x]in之前会看到对out的写入。

因此,假设只有一个读取器和一个作者,那么in,out变量都是在一个线程中修改的。

代码语言:javascript
复制
buffer[in] = next_produced;
in = (in + 1) % BUFFER SIZE;

在读取器中可以看到错误的顺序,使读者看到的是感动,而旧的值却是bufferin。

代码语言:javascript
复制
Item next_consumed = buffer[out];
out = (out + 1) % BUFFER SIZE;

编译器或处理器可能会出错,允许生产者在buffer[out]读取值之前将其写入整个队列,覆盖该值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34805289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档