PV操作(生产者-消费者问题)-1【转帖】
- /*
- caoyuan
- 2006-12-26
- PV operation producer and consumer
- */
- #include <windows.h>
- #include <iostream>
- using namespace std;
- const unsigned short SIZE_OF_BUFFER = 10; //缓冲区长度
- unsigned short ProductID = 0; //产品号
- unsigned short ConsumeID = 0; //将被消耗的产品号
- unsigned short in = 0; //产品进缓冲区时的下标
- unsigned short out = 0; //产品出缓冲区时的下标
- int pv_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列
- bool pv_continue = true; //控制程序结束
- HANDLE pv_hMutex; //用于线程间的互斥,主要用于控制台打印
- HANDLE fullSemaphore; //消费者进程的私用信号量
- HANDLE emptySemaphore; //生产者进程的私用信号量
- DWORD WINAPI Producer(LPVOID); //生产者线程
- DWORD WINAPI Consumer(LPVOID); //消费者线程
- int main()
- {
- //创建Mutex和Semaphore
- pv_hMutex = CreateMutex(NULL,FALSE,NULL);
- fullSemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER,NULL);
- emptySemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER,
- SIZE_OF_BUFFER,NULL);
- //缓冲区初始化
- for (int i = 0; i< SIZE_OF_BUFFER;++i){
- pv_buffer[i] = -1; //当值为-1时该项为空
- }
- const unsigned short PRODUCERS_COUNT = 3; //生产者的个数
- const unsigned short CONSUMERS_COUNT = 2; //消费者的个数
- //总的线程数
- const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT;
- HANDLE pvThreads[THREADS_COUNT]; //各线程的handle
- DWORD producerID[PRODUCERS_COUNT]; //生产者线程的标识符
- DWORD consumerID[CONSUMERS_COUNT]; //消费者线程的标识符
- //创建生产者线程
- for (int i=0;i<PRODUCERS_COUNT;i++){
- pvThreads[i] = CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);
- if (pvThreads[i] == NULL) break;
- }
- //创建消费者线程
- for (int i=0;i<CONSUMERS_COUNT;i++){
- pvThreads[PRODUCERS_COUNT+i]
- =CreateThread(NULL,0,Consumer,NULL,0,&consumerID[i]);
- if (pvThreads[i]==NULL) break;
- }
- while(pv_continue){
- if(getchar()){ //按回车后终止程序运行
- pv_continue = false;
- }
- }
- system("pause");
- return 0;
- }
- //生产一个产品。简单模拟了一下,仅输出新产品的ID号
- void Produce()
- {
- cout << "生产 " << ++ProductID << "号产品 ";
- Sleep(1500);
- cout << " :) " << endl;
- }
- //把新生产的产品放入缓冲区
- void Put()
- {
- cout << "向仓库中放入产品 ";
- pv_buffer[in] = ProductID;
- in = (in+1)%SIZE_OF_BUFFER;
- Sleep(1500);
- cout << ":)" << endl;
- }
- //从缓冲区中取出一个产品
- void Take()
- {
- ConsumeID = pv_buffer[out];
- cout << "从仓库中取出第 "<<ConsumeID<<" 号货物 ";
- pv_buffer[out]= -1;
- out = (out+1)%SIZE_OF_BUFFER;
- Sleep(1500);
- cout << ":)" << endl;
- }
- //消耗一个产品
- void Consume()
- {
- cout << "消费掉第 " << ConsumeID << " 号货物 ";
- Sleep(1500);
- cout << ":)" << endl;
- }
- //生产者
- DWORD WINAPI Producer(LPVOID lpPara)
- {
- while(pv_continue){
- WaitForSingleObject(emptySemaphore,INFINITE); // P(emptySemaphore) 生产者信号量 -1
- WaitForSingleObject(pv_hMutex,INFINITE); // P(Mutex) 获取线程间互斥信号
- Produce();
- Put();
- Sleep(1500);
- ReleaseSemaphore(fullSemaphore,1,NULL); // V(fullSemaphore) 消费者信号量 +1
- ReleaseMutex(pv_hMutex); // V(Mutex) 释放线程间互斥信号
- }
- return 0;
- }
- //消费者
- DWORD WINAPI Consumer(LPVOID lpPara)
- {
- while(pv_continue){
- WaitForSingleObject(fullSemaphore,INFINITE); //P(fullSemaphore) 消费者信号量-1
- WaitForSingleObject(pv_hMutex,INFINITE); //P(Mutex) 获得线程间互斥信号
- Take();
- Consume();
- Sleep(1500);
- ReleaseSemaphore(emptySemaphore,1,NULL); //V(emptySemaphore) 生产者信号量+1
- ReleaseMutex(pv_hMutex); //V(Mutex) 释放线程间互斥信号
- }
- return 0;
- }