在Linux下或者Windows下实现读者写者问题。
写者优先
5个读者,3个写者
如果读者来:
1) 无读者、写者,新读者可以读;
2) 无写者等待,但有其他读者正在读,新读者可以读;
3) 有写者等待,但有其他读者正在读,新读者等;
4) 有写者写,新读者等
如果写者来:
1) 无读者,新写者可以写;
2) 有读者,新写者等待;
写者优先
5个读者,3个写者
如果读者来:
1) 无读者、写者,新读者可以读;
2) 无写者等待,但有其他读者正在读,新读者可以读;
3) 有写者等待,但有其他读者正在读,新读者等;
4) 有写者写,新读者等
如果写者来:
1) 无读者,新写者可以写;
2) 有读者,新写者等待;
3) 有其他写者或等待,新写者等待
题中的要点:
1、多个读者可以同时进行读操作
2、如果有人在写,别人则不能读也不能写
3、读、写者来则排在队列末端。不能让读者插队
综上,读写者之间有互斥,写着与写着之间互斥。两层关系
int main()
{
int id_this;
int shm1;
int shm2;
int shm3;
shm1=shmget(1,8,IPC_CREAT|0777);
shm2=shmget(2,8,IPC_CREAT|0777);
shm3=shmget(3,8,IPC_CREAT|0777);
int *cnt=(int *)shmat(shm1,0,0);
int *buf=(int *)shmat(shm2,0,0);
int *idt=(int *)shmat(shm3,0,0);
*idt=1;
int n;
int mutex_rw;
int mutex_rr;
int mutex_ww;
int mutex;
sem_init();
sem_crea(mutex_rr,1);
sem_crea(mutex_rw,1);
sem_crea(mutex_ww,1);
sem_crea(mutex,1);
*cnt=0;
*buf=0;
int _time;
//每调用一次fork,程序就会由1个变为两个,如果调用两次fork实际上会生成四个进程(类似于一棵树的结构)我们需要创建2的3次方:8个进程。
pid_t p[3];
for(int i=0;i<3;i++)
p[i]=fork();
if(p[0]==0||p[0]!=0&&p[1]==0&&p[2]==0)
{
sleep(1);
printf("proccess reader has been built\n");
while(1)
{
srand((int)time(0));
_time=rand()%3+1;
sleep(_time);
p1(mutex_rw); //防止读者插队的锁
p1(mutex_rr);
int n=*cnt;
n++;
*cnt=n;
if(n==1)p1(mutex); //第一个读者把数据区加锁。
v(mutex_rr);
v(mutex_rw);
printf("reader %d\n",*buf);
p1(mutex_rr);
n=*cnt;
n--;
*cnt=n;
if(n==0)v(mutex);//最后一个读者把锁解开
v(mutex_rr);
}
}
else if(p[0]!=0)
{
sleep(1);
printf("process writer has been built\n");
while(1)
{
srand((int)time(0));
_time=rand()%3+1;
sleep(_time);
p1(mutex_rw);
p1(mutex);
int n=*buf;
n++;
printf("write %d into buf\n",n);
*buf=n;
v(mutex);
v(mutex_rw);
}
}
}
具体的头文件、函数的写法请参考(这个实例中因为有BUG我把P改成了p1)