生产者消费者问题——C++ windows版 多生产者多消费者的队列实现
最进要写一个多线程加载资源的资源管理器(ResourceManager)和多线程音频解码器(MultiThread Decoder)。因为距最近一次用到多线程放下好久了,所以今天把生产者消费者问题练一下手。
为什么选择生产者消费者问题,因为他比较接近资源管理器和多线程音频解码器的原型。
比如,对于音频解码器,音频线程去流式的解码一段MP3格式的内存,就类似生产者生产产品的过程;而音频播放API(如OpenAL,OpenSL)通常需要的是PCM数据,也就是生产者生产的产品,所以播放逻辑充当消费者的角色,典型的生产者消费者问题。
再对于资源管理器,加载Mesh和Texture类似生产单个Resource的过程,而相应的渲染逻辑去使用资源就相当于消费资源的过程,但不同的是最后当不再使用这个资源的时候,这个资源才会被释放,而非使用一次。
今天抽时间,写了一个C++ windows版 多生产者多消费者的队列实现,pthread版估计等需要做跨平台的时候再做,如果想方便直接用OpenMP或者TBB也是可以的,但是对于轻量级引擎,自己实现资源加载器完全足够了。
#include <Windows.h> #include <map> #include <queue>CRITICAL_SECTION g_cs; // mutex HANDLE g_hEmptyBufferSemaphore; HANDLE g_hFullBufferSemaphore;#define INVALID -1#define PRODUCER 5 #define CUSTOMER 5#define NUM_COUNT 8 #define BUFF_SIZE 4static std::queue<int> bufferQueue; static std::map< DWORD,int > countMap;bool ProducerFinish = false;//设置控制台输出颜色 BOOL SetConsoleColor(WORD wAttributes) {HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);if (hConsole == INVALID_HANDLE_VALUE)return FALSE; return SetConsoleTextAttribute(hConsole, wAttributes); }DWORD WINAPI ProducerFunc(LPVOID param) {while(true){WaitForSingleObject( g_hEmptyBufferSemaphore, INFINITE);EnterCriticalSection(&g_cs);DWORD threadId = GetCurrentThreadId();if(countMap.find(threadId) == countMap.end())countMap[threadId] = 0;int productID = ++countMap[threadId];bufferQueue.push( productID);printf("生产者%d , 生产%d\n", threadId, productID);if( productID == NUM_COUNT ){SetConsoleColor(FOREGROUND_RED);printf("生产者%d生产完毕\n",GetCurrentThreadId());SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);LeaveCriticalSection(&g_cs);ReleaseSemaphore(g_hFullBufferSemaphore, 1, NULL);break;}LeaveCriticalSection(&g_cs);ReleaseSemaphore(g_hFullBufferSemaphore, 1, NULL);}return NULL; }DWORD WINAPI CustomerFunc(LPVOID param) {while (true){WaitForSingleObject( g_hFullBufferSemaphore, INFINITE);EnterCriticalSection(&g_cs);int buffer = -1;if(!bufferQueue.empty()){buffer = bufferQueue.front();bufferQueue.pop();}if(buffer != INVALID )printf("消费者%d ,消费%d\n", GetCurrentThreadId() , buffer);if( bufferQueue.empty() && ProducerFinish){printf("消费者%d 结束\n",GetCurrentThreadId());LeaveCriticalSection(&g_cs);// 通知其他消费者可以结束了ReleaseSemaphore( g_hFullBufferSemaphore, 1, NULL);break;}LeaveCriticalSection(&g_cs);ReleaseSemaphore( g_hEmptyBufferSemaphore, 1, NULL);}return NULL; }int _tmain(int argc, _TCHAR* argv[]) {InitializeCriticalSection(&g_cs); g_hEmptyBufferSemaphore = CreateSemaphore( NULL, 4, 4, NULL);g_hFullBufferSemaphore = CreateSemaphore( NULL, 0, 4, NULL);HANDLE producerThreads[PRODUCER];HANDLE customerThreads[CUSTOMER];// producerfor (int i = 0; i < PRODUCER; ++i){producerThreads[i] = CreateThread( NULL, 0, ProducerFunc, NULL, NULL, NULL);}// customersfor (int i = 0; i < CUSTOMER; ++i)customerThreads[i] = CreateThread( NULL, 0, CustomerFunc, NULL, NULL, NULL);WaitForMultipleObjects( PRODUCER, producerThreads, TRUE, INFINITE);ProducerFinish = true;WaitForMultipleObjects( CUSTOMER, customerThreads, TRUE, INFINITE);for (int i = 0; i < PRODUCER; ++i)CloseHandle(producerThreads[i]);for (int i = 0; i < CUSTOMER; ++i)CloseHandle(customerThreads[i]);CloseHandle(g_hEmptyBufferSemaphore);CloseHandle(g_hFullBufferSemaphore);DeleteCriticalSection(&g_cs);countMap.clear();return 0; }
转载于:https://www.cnblogs.com/singmelody/p/3779063.html
生产者消费者问题——C++ windows版 多生产者多消费者的队列实现相关推荐
- Windows线程(生产者与消费者问题)
Windows线程(生产者与消费者问题) 转载 佟强 2008.10.10 生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制.在同一个进程地址空 ...
- 生产者与消费者问题(synchronized版和JUC版)
生产者和消费者问题synchronized版 package com.cc.pc; /** * 线程之间的通信问题:生产者和消费者问题! 等待唤醒,通知唤醒 * 线程交替执行 A B 操作同一个变量 ...
- 多生产者_多线程必考的「生产者 - 消费者」模型,看齐姐这篇文章就够了
生产者 - 消费者模型 Producer-consumer problem 是一个非常经典的多线程并发协作的模型,在分布式系统里非常常见.也是面试中无论中美大厂都非常爱考的一个问题,对应届生问的要少一 ...
- python多线程实现生产者消费者_用Python实现多线程“生产者-消费者”模型的简单例子...
用 Python 实现多线程"生产者 - 消费者"模型的简单例子 生产者消费者问题是一个著名的线程同步问题, 该问题描述如下: 有一个生产者在生产产品, 这些产品将提供给若干个消费 ...
- 生产者消费者_【线程通信】生产者消费者模型
1生产者消费者模型介绍 生产者消费者模型,是每一个学习多线程的的人都需要知道的模型; 大致情况就是:有两个线程,一个负责生产产品,一个消费产品,两者公用同一块内存区域,也就是产品放在了同一块内存上面, ...
- 生产者消费者代码c语言_由生产者消费者模型引出的线程同步问题
由生产者消费者模型引出的线程同步问题 基本生产者消费者模型: 代码示例: 数据模型: /*** Created by IntelliJ IDEA.** @Author: ZhangDong* @Dat ...
- java多线程生产者与消费者案例_多线程操作实例——生产者与消费者
面对多线程学习生产者与消费者是最基本的实例 对于java后端开发的人员必须要掌握,还有考研考试计算机操作系统的同鞋. 下面是三个实例对于生产者与消费者的的例子,层层递进,逐步解决问题. 问题:生产者- ...
- kafka消费者如何读同一生产者消息_Kafka系列3:深入理解Kafka消费者
上面两篇聊了Kafka概况和Kafka生产者,包含了Kafka的基本概念.设计原理.设计核心以及生产者的核心原理.本篇单独聊聊Kafka的消费者,包括如下内容:消费者和消费者组 如何创建消费者 如何消 ...
- 多生产者_【并发那些事】生产者消费者问题
Step 1. 什么是生产者消费者问题 生产者消费者问题也叫有限缓冲问题,是多线程同步的一个最最最经典的问题.这个问题描述的场景是对于一个有固定大小的缓冲区,同时共享给两个线程去使用.而这两个线程会分 ...
最新文章
- 单击“登录”后,用户名和密码显示在地址栏中,不安全
- 机器学习笔记:激活函数
- vue 请求多个api_Vue 创建多人共享博客
- 更改linux子系统软件源为国内镜像
- 77种互联网盈利创新模式(3)
- WordPress响应式Alt_Blog主题 简约博客主题
- 比特币:一种点对点的电子现金系统
- oracle10g静默升级,Linux下静默安装,升级和删除Oracle10g客户端
- 蓝桥杯——阿尔法乘积
- android调用系统的自定义裁剪后得到的图片不清晰,使用MediaStore.EXTRA_OUTPUT获取缓存下的清晰图片...
- ERP系统测试用例设计
- FastStone Capture—屏幕录像
- html5期末大作业:基于HTML+CSS技术实现——传统手工艺术雕刻网站(3页)
- API 服务器健康状态自检
- 异常:The JSP specification requires that an attribute name is preceded by whitespace
- Linux下通过CCID协议与USB设备进行交互经验总结
- 2022年高压电工判断题及答案
- 一位想学习编程拯救他人的初中生
- leetcode学习打卡--572. 另一个树的子树(递归,二叉树遍历)
- Adabins:Transformer+单目深度估计
热门文章
- C语言Socket动态ajax网页,简单的ajax聊天网页 socket
- as本地仓库更改_Android Studio 之 Gradle与Project Structure详解
- mysql 查看主从_什么参数可以查看mysql主从复制是否正常
- editor修改样式 vue_vue-quill-editor的使用及个性化定制操作
- C++知识点9——函数重载,默认实参,内联函数
- rs232 距离_你知道RS232与RS485接口的区别吗?
- go context剖析之使用技巧
- Golang中time包
- 【leetcode】97. Interleaving String
- Webpack 4 api 了解与使用