您的位置:首页 > 其它

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

2017-09-20 09:23 381 查看
昨天很幸运的找到了这个系列的博客 http://blog.csdn.net/morewindows/article/details/7421759, href="http://blog.csdn.net/morewindows/article/details/7421759" target=_blank>点击打开链接

学习了一下关于多线程的知识,前面的系列讲解的非常详细,并且对生产消费这一篇(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;
//}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: