题目概述:
1.A,B,C,D四个进程,A向buf里面写数据,B,C,D向buf里面读数据,当A写完,且B,C,D都读一次后,A才能再写。用P,V操作实现。
题目中有4个进程,然后一个写者,三个读者,对写者来说,写完一个数据后,必须等待3个读者都读完后才能继续写。
此处有A和B、C、D分别互斥,然后A写完后,必须等待BCD都读完后,才能继续写,这是一个同步问题,
所以总结起来就是3个互斥,一个同步问题。
begin
var mutexB,C,D=1, semaphore=0;
writerProcess
写数;
V(mutexB[CD)
P(semaphore)
P(semaphore)
P(semaphore)//等待BCD读
ReadProcess
P(mutexB[CD]) //读数
读数
V(semaphore)
其实现代码如下:
//1.A,B,C,D四个进程,A向buf里面写数据,B,C,D向buf里面读数据,
// 当A写完,且B,C,D都读一次后,A才能再写。用P,V操作实现。
//设置控制台输出颜色
BOOL SetConsoleColor(WORD wAttributes)
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE)
return FALSE;
return SetConsoleTextAttribute(hConsole, wAttributes);
}
HANDLE g_mutexs[3];
HANDLE g_semaphore;
CRITICAL_SECTION g_cs;
int g_buffer;
const int MaxCount = 20; // 最大产品数
// 写者线程
unsigned int __stdcall ProducerThread(LPVOID pv)
{
for ( int i=1; i<=MaxCount; ++i )
{
g_buffer = i;
EnterCriticalSection(&g_cs);
printf("ProducerThread %d produces %d\n",GetCurrentThreadId(), g_buffer);
LeaveCriticalSection(&g_cs);
for ( int i=0; i<3; ++i )
ReleaseSemaphore(g_mutexs[i],1,NULL);
for ( int i=0; i<3; ++i )
WaitForSingleObject(g_semaphore,INFINITE);
}
return 0;
}
// 读者线程
unsigned int __stdcall ReaderThread(LPVOID pv)
{
int index = (int)pv;
while( true )
{
WaitForSingleObject(g_mutexs[index],INFINITE);
int num = g_buffer;
EnterCriticalSection(&g_cs);
SetConsoleColor(FOREGROUND_GREEN);
printf("ReaderThread %d reads %d\n",GetCurrentThreadId(), num);
SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
LeaveCriticalSection(&g_cs);
ReleaseSemaphore(g_semaphore,1,NULL);
if ( num == MaxCount )
break;
}
return 0;
}
void testReadWriter()
{
for ( int i=0; i<3; ++i )
g_mutexs[i] = CreateSemaphore( NULL, 0, 1, NULL );
g_semaphore = CreateSemaphore( NULL, 0, 3, NULL );
InitializeCriticalSection(&g_cs);
HANDLE handles[4];
for ( int i=0; i<3; ++i )
handles[i+1] = (HANDLE)_beginthreadex(NULL, 0, ReaderThread, (LPVOID)i, 0, NULL);
handles[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThread, NULL, 0, NULL);
WaitForMultipleObjects(4, handles, true, INFINITE );
for ( int i=0; i<4; ++i )
CloseHandle(handles[i]);
for ( int i=0; i<3; ++i )
CloseHandle(g_mutexs[i]);
CloseHandle(g_semaphore);
DeleteCriticalSection(&g_cs);
}