操作系统实验,IPC(2): reader and writer, 读者和写者问题

来源:互联网 发布:知其雄守其雌曾国藩 编辑:程序博客网 时间:2024/05/18 04:57

1.首先,关于信号量的问题请看上一篇博客。

2.读者和写者问题分为读者和写者对等且二者都不能多人读取,读者和写者对等但都可以读者可以多人读取,读者优先并且读者可以多人读取。写者优先但是读者可以多人读取。

3.如果是二者对等,不管是不是多人读取,只需要一个互斥量就可以了。这里要说明一点,它和生产者和消费者不一样。生产者和消费者问题的共享资源是有数目的。但是这里没有。

4.如果要实现读者可以多人,必须给读者一个单独的信号量。把读者的进入和离开分成两个步骤。只要读者进入,就释放资源。这样后面的就可以继续进入。

5.要实行读者优先,就可以给读者计数,如果读者的数目刚开始或者最后一个的情况考虑一下就可以了。

6.所以下面的读者可以多人读取并且读者优先就使用了两个信号量。不过应该用反了。应该是读者和写者共享的那个是mutex,复制的时候也是mutex,这里说一下。因为我不想改了,只是觉得写反了。

7.如果写者优先,就需要计数,类似于读者。

8,写者优先还有一个问题,就是如果现在写者在用共享变量,但是后面排队的有读者和写者,这个写者便不释放资源,直接让写一个写者使用资源即可。如此以来,读者就需要一个单独的变量。如前面所说,来保持全部写者之间的轮流。

9,这时候就剩最后一个问题就可以实现写者优先了。就是在读者控制资源的时候,有写者和读者排队,先到的先使用。我们需要一个全局信号量来做。就是来排队。

下面是读者优先的代码

#include<windows.h>   #include<fstream>#include<cstdlib>#include<iostream>#include <ctime>using namespace std;     const int MaxThread=20;             HANDLE hX;    HANDLE hWsem; HANDLE thread[MaxThread]; int readcount; double totaltime;  void WRITEUNIT(int iProcess){        printf("%dth writer begins to write.\n",iProcess);        Sleep((DWORD)(6000));        printf("End of %dth writer  for writing.\n",iProcess); } void READUNIT(int iProcess){        printf("%dth reader begins to read.\n",iProcess);        Sleep((DWORD)(3000));        printf("End of %dth reader  for reading.\n",iProcess);} DWORD   WINAPI   reader(LPVOID   lpVoid){    int iProcess   =   *(int*)lpVoid;    //Sleep((DWORD)(3000));    DWORD wait_for=WaitForSingleObject(hX,INFINITE);        printf("%dth reader requres 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);//use-data-read();    return iProcess;} DWORD   WINAPI   writer(LPVOID   lpVoid){    int iProcess   =   *(int*)lpVoid;    //Sleep((DWORD)(6000));//think-up-data    printf("%d writer requres 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;    int readerThreadNum=0;int writerThreadNum=0;while(writerThreadNum<3&&readerThreadNum<6){if(rand()%3==0){printf("Creating %dth writer",writerThreadNum+1);writerThreadNum = writerThreadNum+1;thread[writerThreadNum]   =   CreateThread(NULL,   0,writer,  &writerThreadNum,0,0); }if(rand()%2==0){//h = CreateThread(NULL, 0, customer_thread, NULL, 0, NULL);printf("Creating %dth reader.\n",readerThreadNum+1);readerThreadNum=readerThreadNum+1;                thread[readerThreadNum]   =   CreateThread(NULL,   0,reader,  &readerThreadNum,0,0); }Sleep(2000);}    Sleep((DWORD)(totaltime*1000));system("pause");    return 1;}

下面是写者优先的代码

#include<windows.h>   #include<fstream>#include<cstdlib>#include<iostream>#include <ctime>using namespace std;     const int MaxThread=20;             HANDLE queue;    HANDLE hWsem; HANDLE hRsem;HANDLE db;HANDLE thread[MaxThread]; int readcount; int writecount;double totaltime;  //写者的写操作void WRITEUNIT(int iProcess){        printf("%dth writer begins to write.\n",iProcess);        Sleep((DWORD)(6000));        printf("End of %dth writer  for writing.\n",iProcess); } //读者的读操作void READUNIT(int iProcess){        printf("%dth reader begins to read.\n",iProcess);        Sleep((DWORD)(3000));        printf("End of %dth reader  for reading.\n",iProcess);} //读者函数DWORD   WINAPI   reader(LPVOID   lpVoid){    int iProcess   =   *(int*)lpVoid;    //Sleep((DWORD)(3000));//检查是否是第一个读者WaitForSingleObject(queue,INFINITE);DWORD wait_for=WaitForSingleObject(hRsem,INFINITE);        printf("%dth reader requres reading.\n",iProcess);        readcount++;        if(readcount==1)WaitForSingleObject(db,INFINITE);ReleaseMutex(hRsem);ReleaseMutex(queue);//读操作,没有信号量,因为不互斥        READUNIT(iProcess);//检查是不是最后一个读者wait_for=WaitForSingleObject(hRsem,INFINITE);        readcount--;        if(readcount==0)        ReleaseSemaphore(db,1,0);ReleaseMutex(hRsem);//use-data-read();    return iProcess;} //写者函数DWORD   WINAPI   writer(LPVOID   lpVoid){    int iProcess   =   *(int*)lpVoid;    //Sleep((DWORD)(6000));//think-up-data    printf("%d writer requres writing.\n",iProcess);//检查是否是第一个写者WaitForSingleObject(hWsem,INFINITE);writecount++;        if(writecount==1)WaitForSingleObject(queue,INFINITE);ReleaseMutex(hWsem);//写操作WaitForSingleObject(db,INFINITE);  WRITEUNIT(iProcess);ReleaseSemaphore(db,1,0);//WaitForSingleObject(hWsem,INFINITE);  //检查是否是最后一个写者WaitForSingleObject(hWsem,INFINITE);writecount--;        if(writecount==0)ReleaseMutex(queue);ReleaseMutex(hWsem);    //ReleaseSemaphore(db,1,0);    return iProcess;}     int main(){    int threadNum;    int threadcount;    ifstream file;     queue=CreateMutex(NULL, FALSE, NULL);hWsem=CreateMutex(NULL, FALSE, NULL);hRsem=CreateMutex(NULL, FALSE, NULL);    db=CreateSemaphore(NULL,1,1,NULL);     //???????????????????    readcount=0;   writecount=0;        int readerThreadNum=0;int writerThreadNum=0;//保证写者不超过3个或者读者不超过6个while(writerThreadNum<3&&readerThreadNum<6){if(rand()%3==0){printf("Creating %dth writer",writerThreadNum+1);writerThreadNum = writerThreadNum+1;thread[writerThreadNum]   =   CreateThread(NULL,   0,writer,  &writerThreadNum,0,0); }if(rand()%2==0){//h = CreateThread(NULL, 0, customer_thread, NULL, 0, NULL);printf("Creating %dth reader.\n",readerThreadNum+1);readerThreadNum=readerThreadNum+1;                thread[readerThreadNum]   =   CreateThread(NULL,   0,reader,  &readerThreadNum,0,0); }Sleep(2000);}    Sleep((DWORD)(totaltime*1000));CloseHandle(db);CloseHandle(queue);CloseHandle(hRsem);CloseHandle(hWsem);//system("pause");    return 1;}



0 0
原创粉丝点击