操做系統綜合實驗選了個讀者寫者問題的題目:用這n個線程來表示n個讀者或寫者,模擬實現"讀者優先"/"寫者優先"/"讀寫同步"這幾個問題. ios
附加: c++
讀者優先的附加限制:若是一個讀者申請進行讀操做時已有另外一個讀者正在進行讀操做,則該讀者可直接開始讀操做。但任何寫者必須等到沒有讀者時才能開始寫操做。 windows
寫者優先的附加限制:若是一個讀者申請進行讀操做時已有另外一寫者在等待訪問共享資源,則該讀者必須等到沒有寫者處於等待狀態後才能開始讀操做。
函數
用到的windows API函數(具體的參數本身baidu/google,我就是這麼作的): ui
CreateThread() 在調用進程的地址空間上建立一個線程 google
ExitThread() 用於結束當前線程 spa
Sleep() 可在指定的時間內掛起當前線程 操作系統
CreateMutex() 建立一個互斥對象,返回對象句柄 線程
OpenMutex() 打開並返回一個已存在的互斥對象句柄,用於後續訪問 對象
ReleaseMutex() 釋放對互斥對象的佔用,使之成爲可用
WaitForSingleObject() 可在指定的時間內等待指定對象爲可用狀態
InitializeCriticalSection() 初始化臨界區對象
EnterCriticalSection() 等待指定臨界區對象的全部權
LeaveCriticalSection() 釋放指定臨界區對象的全部權
CreateSemaphore() 建立一個信號量對象
ReleaseSemaphore() 將所指信號量加上指定大小的一個量
用課本的pv操做寫的PV信號量同步排斥:
//read first 讀者優先
semaphore rmutex,wmutex;
int readcount=0;
cobegin:
process reader_i(){
p(rmutex);
readcount++;
if(readcount==1){
p(wmutex);
}
v(rmutex);
read,.....
p(rmutex);
readcount--;
if(readcount==0){
v(wmutex);
}
v(rmutex);
}
process writer_j(){
p(wmutex);
write,....
v(wmutex);
}
coend
//write first 寫者優先
semaphore rmutex,wmutex,rwmutex;
int readcount=0,writecount=0;
cobegin:
process reader_i(){
p(wmutex);
p(rmutex);
readcount++;
if(readcount==1){
v(rwmutex);
}
v(rmutex);
v(wmutex);
read,....
p(rmutex);
readcount--;
if(readcount==0){
v(rwmutex);
}
v(rmutex);
}
process writer_j(){
p(wmutex);
p(rwmutex);
write,....
v(rwmutex);
v(wmutex);
}
coend
//read write 讀寫同步
semaphore rmutex,wmutex,queue;//高手的寫法,運用queue表示信號量的互斥,reader first/write first也能夠運用這//種寫法
int readcount=0;
cobegin:
process reader_i(){
p(queue);
p(rmutex);
readcount++;
if(readcount==1){
p(wmutex);
}
v(rmutex);
v(queue);
read,.....
p(rmutex);
readcount--;
if(readcount==0){
v(wmutex);
}
v(rmutex);
}
process writer_j(){
p(queue);
p(wmutex);
v(queue);
write,....
v(wmutex);
}
coend
用c++模擬實現「讀者優先」以下:(剩下兩種的實現原理上面以提出,根據下面寫法既可模擬實現)
#include <windows.h>
#include <fstream>
#include <cstdlib>
#include <iostream>
using namespace std;
const int MaxThread=20;
struct ThreadInfo{
int num;
char type;
double start;
double time;
}thread_info[MaxThread];
HANDLE hX;
HANDLE hWsem;
HANDLE thread[MaxThread];
int readcount;
double totaltime;
void WRITEUNIT(int iProcess){
printf("Thread %d begins to writes.\n",iProcess);
Sleep((DWORD)(thread_info[iProcess-1].time*1000));
printf("End of thread %d for writing.\n",iProcess);
}
void READUNIT(int iProcess){
printf("Thread %d begins to read.\n",iProcess);
Sleep((DWORD)(thread_info[iProcess-1].time*1000));
printf("End of thread %d for reading.\n",iProcess);
}
DWORD WINAPI reader(LPVOID lpVoid){
int iProcess = *(int *)lpVoid;
Sleep((DWORD)(thread_info[iProcess-1].start*1000));
DWORD wait_for=WaitForSingleObject(hX,INFINITE);
printf("Thread %d require reading.\n",iProcess);
readcount++;
if(readcount==1) {
WaitForSingleObject(hWsem,INFINITE);
}
ReleaseMutex(hX);
READUNIT(iProcess);
wait_for=WaitForSingleObject(hX,INFINITE);
readcount--;
if(readcount==0)
ReleaseSemaphore(hWsem,1,0);
ReleaseMutex(hX);
return iProcess;
}
DWORD WINAPI writer(LPVOID lpVoid){
int iProcess = *(int *)lpVoid;
Sleep((DWORD)(thread_info[iProcess-1].start*1000));
printf("Thread %d require writing.\n",iProcess);
DWORD wait_for=WaitForSingleObject(hWsem,INFINITE);
WRITEUNIT(iProcess);
ReleaseSemaphore(hWsem,1,0);
return iProcess;
}
int main(){
int threadNum;
int threadcount;
ifstream file;
hX=CreateMutex(NULL,FALSE,NULL);
hWsem=CreateSemaphore(NULL,1,1,NULL);
readcount=0;
threadcount=0;
totaltime=0;
file.open("thread.dat",ios::in);
if(file==0){
printf("File Open Error.\n");
return 0;
}
printf("file is open");
while(file>>threadNum){
thread_info[threadNum-1].num=threadNum;
file>>thread_info[threadNum-1].type;
file>>thread_info[threadNum-1].start;
file>>thread_info[threadNum-1].time;
totaltime+=thread_info[threadNum-1].time;
switch(thread_info[threadNum-1].type){
case 'W':
printf("Creating Thread %d for writing.\n",thread_info[threadNum-1].num);
thread[threadNum-1] = CreateThread(NULL,0,writer,&thread_info[threadNum-1].num,0,0);
break;
case 'R':
printf("Creating Thread %d for reading.\n",thread_info[threadNum-1].num);
thread[threadNum-1] = CreateThread(NULL,0,reader,&thread_info[threadNum-1].num,0,0);
break;
}
threadcount++;
printf(" %d",threadNum);
}
file.close();
Sleep((DWORD)(totaltime*1000));
return 1;
}
運行結果:
附:高手寫法: