操做系统综合实验选了个读者写者问题的题目:用这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;
}
运行结果:
附:高手写法: