OS--writer_reader

原创
2012/12/03 15:03
阅读数 234

操作系统综合实验选了个读者写者问题的题目:用这n个线程来表示n个读者或写者,模拟实现"读者优先"/"写者优先"/"读写同步"这几个问题.

附加:

读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。但任何写者必须等到没有读者时才能开始写操作。

写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。

用到的windows API函数(具体的参数自己baidu/google,我就是这么做的):

CreateThread()          在调用进程的地址空间上创建一个线程

ExitThread()            用于结束当前线程

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;
}


运行结果:

附:高手写法:



展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部