单生产者和单消费者共同操作同一个环形缓冲区的问题
by FlyFlyPeng
问题描述
- 本问题只针对单个生产者进程和单个消费者进程的问题进行讨论。
- 生产者进程和消费者进程之间通过共享内存的方式进行IPC通信。
- 环形缓冲区存放在共享内存中,并且环形缓冲区中环形缓冲单元的个数为
2^N
个(N为大于1的正整数),环形缓冲区的数据结构定义为:#define RING_BUFFER_SIZE N struct RingBuffer{ int w_pos; //环形缓冲区写入位置值 int r_pos; //环形缓冲区读取位置值 data_block data[(1<<N)]; //data_block 是环形缓冲区中所存放的数据单元的类型 }
在创建环形缓冲区之后,RingBuffer 结构体中的成员
w_pos
和r_pos
都被初始化为 0。 - 判断环形缓冲区是否为空的伪代码:
if((w_pos - r_pos) == 0) //判断语句为真,RingBuffer 为空
- 判断环形缓冲区是否为满的伪代码:
if((w_pos - r_pos)%(1<<(N+1)) == (1<<N)) //判断语句为真,RingBuffer 为满
- 生产者进程中的处理逻辑伪代码:
while(1) { if((w_pos - r_pos)%(1<<(N+1)) == (1<<N)) //缓冲区满了 { sleep(1); continue; } //否则,则将数据填入到环形缓冲区中空闲的单元中 data[w_pos%(1<<N)] = some_data; //将需要写入的数据写入到指定的环形缓冲区单元中 w_pos++; //将写入位置向前移动 }
- 消费者进程中的处理逻辑伪代码:
while(1) { if((w_pos - r_pos) == 0)) //缓冲区为空 { sleep(1); continue; } //否则,从环形缓冲区中读取数据出来进行处理 process(data[r_pos%(1<<N)]); //process() 函数只是对读取到的数据进行一个处理 r_pos++; //将读取位置向前移动 }
疑惑?
如果按照上面提出的条件和处理逻辑,当生产者进程和消费者进程同时运行时,如果不加
互斥锁
,上面代码是否会出现Bug
,或者不确定的状态?
而且我想了很多遍生产者和消费者的处理逻辑,他们只会在最后执行语句 w_pos++
和 r_pos++
时改变两个进程都共享的值,虽然 w_pos++
和 r_pos++
的操作不是原子操作的,但是好像是不是原子操作都不会对结果产生影响,我就是在这里思考不清楚!不知道大家对此有什么看法呢?能否举出特殊的栗子来描述一下。
Subscribe via RSS