windows c语言 线程同步,WIN32多线程五 线程同步机制Semaphore

/*生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出;很多计算机问题都可以抽象为生产者-消费者问题。

* 有1个生产者生产商品放到环形buffer中供5个消费者消费;生产者每次最多生产5个商品,消费者每次消费1个。

* 要解决这个问题,我们必须确保:(1)并且当缓冲区中没有商品时,消费者不能消费,缓冲区满时,生产者也不能生产商品 (2)不同消费者  * 不能同时消费同一个商品;

*

* 解决(1)我们用一个生产者信号量表示生产者者资源,即空闲buffer数量;用一个消费者信号量表示消费者资源,即非空闲buffer数量。

* 解决(2)我们用一个互斥量Mutex,得到这个Mutex的消费者才能消费。*/#include#include#include#defineASSERT(a) if (!(a)) \exit(EXIT_FAILURE)#defineMAX_PRODUCE_COUNT    5//生产者每次最多生产数量#defineCONSUMER_COUNT        5//消费者数量#defineBUFFER_SIZE        20//缓冲区大小#defineSLEEP_TIME        600#defineWM_FORCE_PAINT        (WM_APP+10)voidProduceAndConsume();voidEndProduceConsume();

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) ;//Win32窗口回调函数DWORD    WINAPI    ProducerThread(LPVOID pVoid);//生产者线程函数DWORD    WINAPI    ConsumerThread(LPVOID pVoid);//消费者线程函数intiProducerPointer;//生产者指针,指向可以放商品的的位置intiConsumerPointer;//消费者指针,指向可以消费商品的位置HANDLE        hProducerSemaphore;//生产者信号量,初始有20个资源HANDLE        hConsumerSemaphore;//消费者信号量,初始有0个资源HANDLE        hConsumerMutex;//生产者MutexHANDLE        hProducerThread;//生产者线程,不断生产商品HANDLE        hConsumersThread[CONSUMER_COUNT];//消费者线程,不断消费商品HWND        hWnd;intWINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine,intiCmdShow)

{staticTCHAR szAppName[]=TEXT("生长者消费者") ;

MSG        msg ;

WNDCLASS    wndclass ;

wndclass.style=CS_HREDRAW|CS_VREDRAW ;

wndclass.lpfnWndProc=WndProc ;

wndclass.cbClsExtra=0;

wndclass.cbWndExtra=0;

wndclass.hInstance=hInstance ;

wndclass.hIcon=LoadIcon (NULL, IDI_APPLICATION) ;

wndclass.hCursor=LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground=(HBRUSH) GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName=NULL ;

wndclass.lpszClassName=szAppName ;if(!RegisterClass (&wndclass))

{

MessageBox (  NULL, TEXT ("This program requires Windows NT!"),

szAppName, MB_ICONERROR) ;return0;

}

hWnd=CreateWindow( szAppName,

TEXT ("生长者消费者"),

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

NULL,

NULL,

hInstance,

NULL) ;

ShowWindow (hWnd, iCmdShow) ;

UpdateWindow (hWnd) ;

ProduceAndConsume();//创建生产者消费者线程、信号量、Mutex,并运行while(GetMessage (&msg, NULL,0,0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

EndProduceConsume();return(int)msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{intiTemp;intiXStart,iYStart;

HDC             hdc ;

HBRUSH        hBrush;

PAINTSTRUCT    ps ;

RECT        rect;

MSG        msg;switch(message)

{caseWM_CREATE:return0;caseWM_FORCE_PAINT:

InvalidateRect(hWnd, NULL, TRUE);while(PeekMessage(&msg, hWnd, WM_FORCE_PAINT, WM_FORCE_PAINT, PM_REMOVE))

;return0;caseWM_PAINT:

hdc=BeginPaint (hwnd,&ps) ;

GetClientRect(hWnd,&rect);

iXStart=(rect.right-rect.left)/2-200;

iYStart=(rect.bottom-rect.top)/2-10;

hBrush=SelectObject(hdc, (HBRUSH)GetStockObject(GRAY_BRUSH));

iTemp=iConsumerPointer;while(TRUE)

{

Rectangle(hdc, iXStart+iTemp*20, iYStart, iXStart+(iTemp+1)*20, iYStart+20);if(++iTemp>=BUFFER_SIZE)

iTemp=0;if(iTemp==iProducerPointer)break;

}

SelectObject(hdc, hBrush);while(TRUE)

{

Rectangle(hdc, iXStart+iTemp*20, iYStart, iXStart+(iTemp+1)*20, iYStart+20);if(++iTemp>=BUFFER_SIZE)

iTemp=0;if(iTemp==iConsumerPointer)break;

}

EndPaint (hwnd,&ps) ;return0;caseWM_DESTROY:

PostQuitMessage (0) ;return0;

}returnDefWindowProc (hwnd, message, wParam, lParam) ;

}

DWORD WINAPI ProducerThread(LPVOID pVoid)

{inti;intiRandom;while(TRUE)

{

srand((unsigned)time(NULL));

iRandom=rand()%MAX_PRODUCE_COUNT;if(iRandom==0)

iRandom++;//生产者申请iRandom个资源for(i=0; i

ASSERT( WAIT_OBJECT_0==WaitForSingleObject(hProducerSemaphore, INFINITE) );//生产者生产iRandom个商品iProducerPointer=iProducerPointer+iRandom;if(iProducerPointer>=BUFFER_SIZE)

iProducerPointer=iProducerPointer-BUFFER_SIZE;

SendMessage(hWnd, WM_FORCE_PAINT,0,0);

Sleep(SLEEP_TIME);//生产者生产了iRandom个商品,消费者有更多的商品消费了;所以为消费者释放iRandom个资源ASSERT(ReleaseSemaphore(hConsumerSemaphore, (long)iRandom, NULL));

}return0;

}

DWORD WINAPI ConsumerThread(LPVOID pVoid)

{while(TRUE)

{//消费者申请到Semaphore和Mutex后,才能消费ASSERT( WAIT_OBJECT_0==WaitForSingleObject(hConsumerSemaphore, INFINITE) );

ASSERT( WAIT_OBJECT_0==WaitForSingleObject(hConsumerMutex, INFINITE) );//消费者消费一个商品iConsumerPointer++;if(iConsumerPointer>=BUFFER_SIZE)

iConsumerPointer=0;

SendMessage(hWnd, WM_FORCE_PAINT,0,0);

Sleep(SLEEP_TIME/2);//消费者释放MutexASSERT(ReleaseMutex(hConsumerMutex));//消费者消费了一个商品,buffer中多了一个空闲位置,为生产者释放一个资源ASSERT(ReleaseSemaphore(hProducerSemaphore, (long)1, NULL));

}return0;

}voidProduceAndConsume()

{inti;

DWORD    dwThreadID;

iProducerPointer=0;

iConsumerPointer=0;

hProducerSemaphore=CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);//创建生产者信号量,初始有20个资源hConsumerSemaphore=CreateSemaphore(NULL,0, BUFFER_SIZE, NULL);//创建消费者信号量,初始有0个资源hConsumerMutex=CreateMutex(NULL, FALSE, NULL);//创建消费者MutexhProducerThread=CreateThread(NULL,0, ProducerThread, NULL,0,&dwThreadID);for(i=0; i

{

hConsumersThread[i]=CreateThread(NULL,0, ConsumerThread, NULL,0,&dwThreadID);

}

}voidEndProduceConsume()

{inti;

ASSERT(CloseHandle(hProducerSemaphore));

ASSERT(CloseHandle(hConsumerSemaphore));

ASSERT(CloseHandle(hConsumerMutex));

ASSERT(CloseHandle(hProducerThread));for(i=0; i

{

ASSERT(CloseHandle(hConsumersThread[i]));

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值