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