读者写者问题

1.允许多个读者可以同时对文件执行读操作
2.只允许一个写者往文件写信息
3.任一写者在完成写操作之前不允许其他读者后写者工作
4.写者执行写操作前,应该让已有的读者或者写者全部退出

读者优先
1.初始化
semaphore wmutex=1;//实现对文件的互斥访问,表示当前是否有进程在访问共享文件
int readcount=0;//记录当前有多少个读进程在访问文件
semaphore rmutex;//用于保证对readcount变量的互斥访问
2.写者
writer(){
	while(1){
		P(wmutex);//写之前加锁
		写文件...
		V(wmutex);//写之后解锁
		}
	}
3.读者
reader(){
	while(1){
		P(rmutex);//各读进程互斥访问readcount
		readcount++;//访问文件读进程数+1
		if(readcount==1)
			P(wmutex);//写进程加锁,不允许在读操作过程中执行写操作
		V(rmutex);
		读文件...           //上面这一部分使得多个读者能够同时访问
		P(rmutex);//各读进程互斥访问raeadcount
		readcount--;//每当一个读进程完成读操作,读者数量-1
		if(readcount==0)
			V(wmutex);//当没有读者,读操作结束后,写进程解锁
		V(rmutex);
		}
	}
写者优先
1.初始化
int readcount=0;//记录当前有多少个读进程在访问文件
int writecount=0;//当writecount=0,唤醒读者
semaphore mutex1;//用于保证对readcount变量的互斥访问
semaphore mutex2;//用于保证对writecount变量的互斥访问

semaphore mutex;//用于保证写者之间的互斥访问,其他读者要进入rmutex之前需要在mutex上排队
semaphore rmutex=1;//当有新写者来时,停止所有的读进程。
semaphore wmutex=1;//实现对写操作地互斥访问

2.读者
reader(){
	while(1){
		P(mutex);//实现写者优先访问,禁止读者在rmutex排队,保证一次只有一个读者进程访问rmutex
			P(rmutex);//读者进程加锁
				P(mutex1);//互斥修改readcount变量
					readcount++;
					if(readcount==1)
						P(wmutex);//当有读者进程执行读操作时,对写者进程加锁
				V(mutex1);
			V(rmutex);//读者进程解锁
		V(mutex);
			读文件...
		P(mutex1);//互斥修改readcount变量
			readcount--;
			if(readcount==0)
				V(wmutex);//当读者数量为0,解锁写者进程,允许写者进程执行写操作
		V(mutex1);
		}
	
3.写者
writer(){
	while(1){
		P(mutex2);//各写者进程互斥访问writecount
			writecount++;//写进程数量+1
			if(writecount==1)
				P(rmutex);//有写进程时,对读进程加锁
		V(mutex2);
		P(wmutex);//写之前加锁,保证每次只有一个写者可以进行写操作
			写文件...
		V(wmutex);
		P(mutex2);
			writecount--;//每当有一个写进程完成写操作,写者数量-1
			if(writecount==0)
				V(rmutex);//若没有写进程正在执行,解锁读者进程
		V(mutex2);
		}
	}

当有一个写者要执行写操作时,P(mutex2)加锁,写者数+1,当此时是第一个写者时,对读进程加锁,禁止在进行写操作过程读进程进行访问,完成对writecount的修改后,V(mutex2)解锁。

(当有多个写进程进行访问时,最先的一个写进程能够进入临界区执行写操作,其他写进程在writecount++后,会被阻塞在P(wmutex)这一步)

P(wmutex)加锁,写进程执行写操作,在改进程未完成时,由于wmutex=0,其他写进程会被阻塞在临界区前,即不能执行写操作,写操作完成后,V(wmutex)解锁。

此时写者数量需要减1,P(mutex2)加锁,修改writecount,当写者数为0,V(rmutex)唤醒读者进程。

所以,对于写者进程信号量mutex2 是为了保证互斥地访问writecount变量,对它的修改。
wmutex 是为了互斥地访问写操作。

4.考虑读者1->写者1->读者2的情况

读者1按照读进程执行到读文件操作,假设此时有一个写进程,由于在执行读进程1时执行了以下语句

if(readcount==1)
	P(wmutex);//当有读者进程执行读操作时,对写者进程加锁

写进程会被阻塞在写操作前,而读者2进程由于写者进程1执行了以下语句

if(writecount==1)
	P(rmutex);//有写进程时,对读进程加锁

读者2进程会被阻塞在P(rmutex)这一步。
当读者1进程执行完读操作,对写进程解锁后,此时wmutex=1

		读文件...
		P(mutex1);//互斥修改readcount变量
			readcount--;
			if(readcount==0)
				V(wmutex);//当读者数量为0,解锁写者进程,允许写者进程执行写操作
		V(mutex1);

写者进程继续执行写操作

P(wmutex);//写之前加锁,保证每次只有一个写者可以进行写操作
			写文件...
		V(wmutex);
		P(mutex2);
			writecount--;//每当有一个写进程完成写操作,写者数量-1
			if(writecount==0)
				V(rmutex);//若没有写进程正在执行,解锁读者进程
		V(mutex2);

执行完写操作后,解锁读者进程,rmutex=1,读者2进程继续执行。

可以看出在这种情况下,写者进程不需要等待所有读者进程完成读操作后才能执行写操作,实现了写者优先。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐