
《计算机操作系统》实验报告
题 目 读者写者问题
学院(部) 信息学院
专 业 计算机科学与技术
班 级
学生姓名
学 号
指导教师(签字)
一、问题描述
一个数据文件或者记录,可以被多个进程共享,我们把只要求读该文件的进程称为“Reader进程”,其他进程则称为“Writer进程”。允许多个进程同时读一个共享对象,因为读操作不会是数据文件混乱。但不允许一个Writer进程和其他Reader进程或者Writer进程同时访问共享对象,因为这种访问将会引起混乱。所谓“读者——写着问题(Reader—Writer Problem)”是指保证一个Writer进程必须与其他进程互斥地访问共享对象的同步问题
二、解决问题
为实现Reader与Writer进程间在读或写是的互斥而设置了一个互斥的信号量Wmutex。另外,在设置一个整型变量Readcount表示正在读的进程数目。由于只要有一个Reader进程在读,便不允许Writer去写。因此,仅当Readercount=0时,表示尚无Reader进程在读时,Reader进程才需要进行Wait(wmutex)操作。若Wait(Wmutex)操作成功,Reader进程便可去读,相应地,做Readcount+1操作。同理,仅当Reader进程在执行了Readercount-1操作后其值为0时,才执行Signal(Wmutex)操作,以便让Writer进程写。又因为Readercount是一个可被多个Reader进程访问的临界资源,因此也应该为它设置一个互斥信号量rmutex。
三、代码实现
1、读者优先
#include #include using namespace std; CRITICAL_SECTION rmutex,wmutex; int wr; int readernum; DWORD WINAPI reader(LPVOID IpParamter){ cout<<"读者申请\\n"; wr++; EnterCriticalSection(&rmutex); if(readernum==0) EnterCriticalSection(&wmutex); readernum++; cout<<"读者进入成功正在读取\\n"; LeaveCriticalSection(&rmutex); Sleep(2000); EnterCriticalSection(&rmutex); readernum--; cout<<"读者退出\\n"; wr--; if(readernum==0) LeaveCriticalSection(&wmutex); LeaveCriticalSection(&rmutex); return 0; } DWORD WINAPI writer(LPVOID PM){ cout<<"写者申请\\n"; while(wr!=0){ } EnterCriticalSection(&wmutex); cout<<"写者已进入正在写入\\n"; Sleep(500); cout<<"写者退出\\n"; LeaveCriticalSection(&wmutex); return 0; } int main(){ readernum=0; wr=0; InitializeCriticalSection(&rmutex); InitializeCriticalSection(&wmutex); HANDLE hr[5];//定义读者线程 HANDLE hw[5];//定义写者线程 //int thnum; int drn=0; //输入的读者个数 int dwn=0; //输入的写者个数 cout<<"输入读者写者线程 1代表读者 2代表写者 0代表结束"< int num=0; cin>>th[num]; while(th[num]){ if(th[num]==1){ drn++; } if(th[num]==2){ dwn++; } num++; cin>>th[num]; } int hr1=0,hw1=0; for(int j=0;j!=num;j++){ if(th[j]==1){ hr[hr1]=CreateThread(NULL,0,reader,NULL,0,NULL); hr1++; } if(th[j]==2){ hw[hw1]=CreateThread(NULL,0,writer,NULL,0,NULL); hw1++; } } WaitForMultipleObjects(drn, hr, TRUE, INFINITE); WaitForMultipleObjects(dwn, hw, TRUE, INFINITE); for(int i=0;i!=drn;i++){ CloseHandle(hr[i]); } for(int i=0;i!=dwn;i++){ CloseHandle(hw[i]); } DeleteCriticalSection(&rmutex); DeleteCriticalSection(&wmutex); return 0; } 2、写者优先 #include #include using namespace std; CRITICAL_SECTION rmutex,wmutex; int ww; int readernum; DWORD WINAPI reader(LPVOID IpParamter){ cout<<"读者申请\\n"; while(ww!=0){ } EnterCriticalSection(&rmutex); if(readernum==0){ EnterCriticalSection(&wmutex); } cout<<"读者进入成功正在读取\\n"; readernum++; LeaveCriticalSection(&rmutex); Sleep(2000); EnterCriticalSection(&rmutex); readernum--; if(readernum==0) LeaveCriticalSection(&wmutex); cout<<"读者退出\\n"; LeaveCriticalSection(&rmutex); return 0; } DWORD WINAPI writer(LPVOID PM){ ww++; cout<<"写者申请\\n"; EnterCriticalSection(&wmutex); cout<<"写者已进入正在写入\\n"; Sleep(1000); cout<<"写者退出\\n"; ww--; LeaveCriticalSection(&wmutex); return 0; } int main(){ readernum=0; ww=0; InitializeCriticalSection(&rmutex); InitializeCriticalSection(&wmutex); HANDLE hr[5];//定义读者线程 HANDLE hw[5];//定义写者线程 int drn=0; //输入的读者个数 int dwn=0; //输入的写者个数 cout<<"输入读者写者线程 1代表读者 2代表写者 0代表结束"< int num=0; cin>>th[num]; while(th[num]){ if(th[num]==1){ drn++; } if(th[num]==2){ dwn++; } num++; cin>>th[num]; } int hr1=0,hw1=0; for(int j=0;j!=num;j++){ if(th[j]==1){ hr[hr1]=CreateThread(NULL,0,reader,NULL,0,NULL); Sleep(10); hr1++; } if(th[j]==2){ hw[hw1]=CreateThread(NULL,0,writer,NULL,0,NULL); Sleep(10); hw1++; } } WaitForMultipleObjects(drn, hr, TRUE, INFINITE); WaitForMultipleObjects(dwn, hw, TRUE, INFINITE); for(int i=0;i!=drn;i++){ CloseHandle(hr[i]); } for(int i=0;i!=dwn;i++){ CloseHandle(hw[i]); } DeleteCriticalSection(&rmutex); DeleteCriticalSection(&wmutex); return 0; } 3、执行结果 读者优先 在读者优先中先两个读者申请,再一个写者申请,再有两个读者申请。当读者和写者发生申请冲突时,读者优先进入读取。 写者优先 在写者优先中,先进入两个读者申请,再一个写者申请,最后两个读者申请。写者和最后两个读者发生申请冲突时,优先让写者先进入,进行写操作。
