学习多线程的生产者和消费者系列的相关实践

来源:互联网 发布:守望先锋a卡优化补丁 编辑:程序博客网 时间:2024/06/11 08:27

昨天很幸运的找到了这个系列的博客 http://blog.csdn.net/morewindows/article/details/7421759,点击打开链接

学习了一下关于多线程的知识,前面的系列讲解的非常详细,并且对生产消费这一篇(csdn博客无法打开,在其他网址浏览的)做了相关的代码实践记录如下备忘:

/////////////////////情景1:////////////////////1生产者 1消费者 1缓冲区  //使用二个事件,一个表示缓冲区空,一个表示缓冲区满。  //再使用一个关键段来控制缓冲区的访问//#include <stdio.h>  //#include <process.h>  //#include <windows.h>////CRITICAL_SECTION  g_csThreadCode;//HANDLE  g_hEventFull;//表示缓冲区满//HANDLE  g_hEventEmpty;//表示缓冲区空////volatile long Datanum; //每次产生或者读取的数据//const int END_PRODUCE_NUMBER = 10;   //生产产品个数//unsigned int __stdcall ProduceThread(void *pPM) {//for (int i = 0; i < END_PRODUCE_NUMBER; i++) {//WaitForSingleObject(g_hEventEmpty, INFINITE); //等待"缓冲区空"事件被触发//InitializeCriticalSection(&g_csThreadCode);//Datanum = i;//printf("产生数据:%d\n",Datanum);//LeaveCriticalSection(&g_csThreadCode);//SetEvent(g_hEventFull); //触发"缓冲区满"事件//}//return 0;//}//unsigned int __stdcall ConsumeThread(void *pPM) {//int ReadData;//for (int i = 0; i < END_PRODUCE_NUMBER; i++) {//WaitForSingleObject(g_hEventFull, INFINITE); //等待"缓冲区满"事件被触发//InitializeCriticalSection(&g_csThreadCode);//ReadData = Datanum;//printf("消费数据:%d\n", ReadData);//LeaveCriticalSection(&g_csThreadCode);//SetEvent(g_hEventEmpty); //触发"缓冲区满"事件////}//return 0;//}//int main() {//////初始化//g_hEventFull = CreateEvent(NULL, FALSE, FALSE, NULL);//初始化时将 “g_hEventFull “事件设置为FALSE未激发态//g_hEventEmpty = CreateEvent(NULL, FALSE, TRUE, NULL);// 初始化时将 “g_hEventEmpty“事件设置为TRUE激发态////InitializeCriticalSection(&g_csThreadCode);//const int THREADNUM = 2;//HANDLE hThread[THREADNUM];//hThread[0] =(HANDLE)_beginthreadex(NULL, 0, ProduceThread, NULL, 0, NULL);//hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumeThread, NULL, 0, NULL);//WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);//CloseHandle(hThread[0]);//CloseHandle(hThread[1]);//////销毁事件和关键段  //CloseHandle(g_hEventFull);//CloseHandle(g_hEventEmpty);//DeleteCriticalSection(&g_csThreadCode);//system("pause");//return 0;//}/////////////////////情景2://////////////////////1生产者 2消费者 4缓冲区  //用一个信号量A来记录为空的缓冲区个数,另一个信号量B记录非空的缓冲区个数,//然后生产者等待信号量A,消费者等待信号量B就可以了//再使用一个关键段来控制缓冲区的访问//#include <stdio.h>  //#include <process.h>  //#include <windows.h>//const int END_PRODUCE_NUMBER = 8;  //生产产品个数  //const int BUFFER_SIZE = 4;          //缓冲区个数  //int g_Buffer[BUFFER_SIZE];          //缓冲池  //int g_i, g_j;////信号量与关键段  //CRITICAL_SECTION g_cs;//HANDLE g_hSemaphoreBufferEmpty, g_hSemaphoreBufferFull;////生产者线程函数  //unsigned int __stdcall ProducerThreadFun(PVOID pM)//{//for (int i = 1; i <= END_PRODUCE_NUMBER; i++)//{////等待有空的缓冲区出现  //WaitForSingleObject(g_hSemaphoreBufferEmpty, INFINITE);//////互斥的访问缓冲区  //EnterCriticalSection(&g_cs);//g_Buffer[g_i] = i;//printf("生产者在缓冲池第%d个缓冲区中投放数据%d\n", g_i, g_Buffer[g_i]);//g_i = (g_i + 1) % BUFFER_SIZE;//LeaveCriticalSection(&g_cs);//////通知消费者有新数据了  //ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);//}//printf("生产者完成任务,线程结束运行\n");//return 0;//}////消费者线程函数  //unsigned int __stdcall ConsumerThreadFun(PVOID pM)//{//while (true)//{////等待非空的缓冲区出现  //WaitForSingleObject(g_hSemaphoreBufferFull, INFINITE);//////互斥的访问缓冲区  //EnterCriticalSection(&g_cs);////printf("  编号为%d的消费者从缓冲池中第%d个缓冲区取出数据%d\n", GetCurrentThreadId(), g_j, g_Buffer[g_j]);//if (g_Buffer[g_j] == END_PRODUCE_NUMBER)//结束标志  //{//LeaveCriticalSection(&g_cs);////通知其它消费者末尾的数据(结束标志)  //ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);//Full信号量++// //不再移动缓冲池中的区块下标,因为已经取到了最后的一个数据//break;//}////g_j = (g_j + 1) % BUFFER_SIZE;//移动缓冲池中的区块下标,为了下次取数据//LeaveCriticalSection(&g_cs);//////ReleaseSemaphore(g_hSemaphoreBufferEmpty, 1, NULL);//Empty信号量++//}////printf("  编号为%d的消费者收到通知,线程结束运行\n", GetCurrentThreadId());//return 0;//}//int main() {////InitializeCriticalSection(&g_cs);////初始化信号量,一个记录有产品的缓冲区个数,另一个记录空缓冲区个数.  //g_hSemaphoreBufferEmpty = CreateSemaphore(NULL, 4, 4, NULL);//当前4个资源,最大允许4个同时访问 //g_hSemaphoreBufferFull = CreateSemaphore(NULL, 0, 4, NULL);//当前0个资源,最大允许4个同时访问 //g_i = 0;//g_j = 0;//memset(g_Buffer, 0, sizeof(g_Buffer));//const int THREADNUM = 3;//HANDLE hThread[THREADNUM];////生产者线程  //hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);////消费者线程  //hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);//hThread[2] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);//WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);//for (int i = 0; i < THREADNUM; i++)//CloseHandle(hThread[i]);//////销毁信号量和关键段  //CloseHandle(g_hSemaphoreBufferEmpty);//CloseHandle(g_hSemaphoreBufferFull);//DeleteCriticalSection(&g_cs);//system("pause");//return 0;//}/////////////////////情景3://///////////////////////2生产者 2消费者 4缓冲区  //用一个信号量A来记录为空的缓冲区个数,另一个信号量B记录非空的缓冲区个数,//然后生产者等待信号量A,消费者等待信号量B就可以了//再使用一个关键段来控制缓冲区的访问//#include <stdio.h>  //#include <process.h>  //#include <windows.h>//volatile BOOL ProRun;              //生产者线程控制标志//volatile int iData;   //产品的标注//const int END_PRODUCE_NUMBER = 8;  //生产产品个数  //const int BUFFER_SIZE = 4;         //缓冲区个数  //int g_Buffer[BUFFER_SIZE];         //缓冲池  //int g_i, g_j;////信号量与关键段  //CRITICAL_SECTION g_cs;//HANDLE g_hSemaphoreBufferEmpty, g_hSemaphoreBufferFull;//////设置控制台输出颜色  //BOOL SetConsoleColor(WORD wAttributes)//{//HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);//if (hConsole == INVALID_HANDLE_VALUE)//return FALSE;////return SetConsoleTextAttribute(hConsole, wAttributes);//}//////生产者线程函数  //unsigned int __stdcall ProducerThreadFun(PVOID pM)//{//while (ProRun)//{////等待有空的缓冲区出现  //WaitForSingleObject(g_hSemaphoreBufferEmpty, INFINITE);//////互斥的访问缓冲区  //EnterCriticalSection(&g_cs);//iData++;//if (iData > END_PRODUCE_NUMBER)//结束标志,所有数据已经生产完毕//{//ProRun = FALSE;//通知其他生产者结束线程//LeaveCriticalSection(&g_cs);//break;//}//else//{//g_Buffer[g_i] = iData;//printf("编号为%d的生产者在缓冲池第%d个缓冲区中投放数据%d\n", GetCurrentThreadId(), g_i, g_Buffer[g_i]);//g_i = (g_i + 1) % BUFFER_SIZE;//LeaveCriticalSection(&g_cs);////通知消费者有新数据了  //ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);//}//}////printf("编号为%d生产者完成任务,线程结束运行\n", GetCurrentThreadId());//return 0;//}//////消费者线程函数  //unsigned int __stdcall ConsumerThreadFun(PVOID pM)//{//while (true)//{////等待非空的缓冲区出现  //WaitForSingleObject(g_hSemaphoreBufferFull, INFINITE);//////互斥的访问缓冲区  //EnterCriticalSection(&g_cs);//SetConsoleColor(FOREGROUND_GREEN);//printf("  编号为%d的消费者从缓冲池中第%d个缓冲区取出数据%d\n", GetCurrentThreadId(), g_j, g_Buffer[g_j]);//SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN| FOREGROUND_BLUE);//if (g_Buffer[g_j] == END_PRODUCE_NUMBER)//结束标志  //{//LeaveCriticalSection(&g_cs);////通知其它消费者末尾的数据(结束标志)  //ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);//Full信号量++//  //不再移动缓冲池中的区块下标,因为已经取到了最后的一个数据//break;//}////g_j = (g_j + 1) % BUFFER_SIZE;//移动缓冲池中的区块下标,为了下次取数据//LeaveCriticalSection(&g_cs);//////ReleaseSemaphore(g_hSemaphoreBufferEmpty, 1, NULL);//Empty信号量++//}//SetConsoleColor(FOREGROUND_GREEN);//printf("  编号为%d的消费者收到通知,线程结束运行\n", GetCurrentThreadId());//SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//return 0;//}//int main() {////InitializeCriticalSection(&g_cs);////初始化信号量,一个记录有产品的缓冲区个数,另一个记录空缓冲区个数.  //g_hSemaphoreBufferEmpty = CreateSemaphore(NULL, 4, 4, NULL);//当前4个资源,最大允许4个同时访问 //g_hSemaphoreBufferFull = CreateSemaphore(NULL, 0, 4, NULL);//当前0个资源,最大允许4个同时访问//ProRun = TRUE;//iData = 0;//g_i = 0;//g_j = 0;////memset(g_Buffer, 0, sizeof(g_Buffer));//const int THREADNUM = 4;//HANDLE hThread[THREADNUM];////生产者线程  //hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);//hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);////消费者线程  //hThread[2] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);//hThread[3] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);//WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);//for (int i = 0; i < THREADNUM; i++)//CloseHandle(hThread[i]);//////销毁信号量和关键段  //CloseHandle(g_hSemaphoreBufferEmpty);//CloseHandle(g_hSemaphoreBufferFull);//DeleteCriticalSection(&g_cs);//system("pause");//return 0;//}