1.背景
看下面的代码,定义一个整型变量counter,并初始化为0。每当向缓冲区增加一项时,递增counter;每当从缓冲区移走一项时,递减counter。
while (true)
{
while (counter == BUFFER_SIZE)
;/*do nothing*/
buffer[in] = next_produced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
while (true)
{
while (counter == 0)
;/*do nothing*/
next_consumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
count--;
}
在代码角度看,程序没有问题,但是我们的系统是分时操作系统,有时间片,比如执行到counter++,结果已经在寄存器上了,但是此时时间片到了,每来得及写入counter的内存,就执行counter--,这时就会出现错误。像这样,多个进程并发地访问同一个资源,并且执行结果与特定的顺序有关,称为竞争条件。
具体Peterson算法请观看我的另一篇文章
2.代码
这里我采用“吃蛋糕”的情景来模拟,即一共有15块蛋糕,每次每个人只能吃一块(每减少一个记录剩余量),即蛋糕是临界资源。创建两个进程eat0和eat1分别来模拟吃蛋糕,两个人吃蛋糕会有1秒钟的延迟。采用C语言模拟算法,因为蛋糕是临界资源,所以两个进程之间存在竞争关系。
2.1没有锁的代码
#include<unistd.h>
#include<stdio.h>
#include<pthread.h>
static int cakes = 15;//总蛋糕数块数
static int count=0;//被吃的蛋糕总数
void* eat0(void* arg)
{
while(cakes>0)
{
sleep(1);
cakes--;
count++;
printf("吃一块蛋糕