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

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

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

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

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

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

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

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

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

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

下面是读者优先的代码

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



你可能感兴趣的:(操作系统实验)