最进要写一个多线程加载资源的资源管理器(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版 多生产者多消费者的队列实现相关推荐

  1. Windows线程(生产者与消费者问题)

    Windows线程(生产者与消费者问题) 转载 佟强 2008.10.10 生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制.在同一个进程地址空 ...

  2. 生产者与消费者问题(synchronized版和JUC版)

    生产者和消费者问题synchronized版 package com.cc.pc; /** * 线程之间的通信问题:生产者和消费者问题! 等待唤醒,通知唤醒 * 线程交替执行 A B 操作同一个变量 ...

  3. 多生产者_多线程必考的「生产者 - 消费者」模型,看齐姐这篇文章就够了

    生产者 - 消费者模型 Producer-consumer problem 是一个非常经典的多线程并发协作的模型,在分布式系统里非常常见.也是面试中无论中美大厂都非常爱考的一个问题,对应届生问的要少一 ...

  4. python多线程实现生产者消费者_用Python实现多线程“生产者-消费者”模型的简单例子...

    用 Python 实现多线程"生产者 - 消费者"模型的简单例子 生产者消费者问题是一个著名的线程同步问题, 该问题描述如下: 有一个生产者在生产产品, 这些产品将提供给若干个消费 ...

  5. 生产者消费者_【线程通信】生产者消费者模型

    1生产者消费者模型介绍 生产者消费者模型,是每一个学习多线程的的人都需要知道的模型; 大致情况就是:有两个线程,一个负责生产产品,一个消费产品,两者公用同一块内存区域,也就是产品放在了同一块内存上面, ...

  6. 生产者消费者代码c语言_由生产者消费者模型引出的线程同步问题

    由生产者消费者模型引出的线程同步问题 基本生产者消费者模型: 代码示例: 数据模型: /*** Created by IntelliJ IDEA.** @Author: ZhangDong* @Dat ...

  7. java多线程生产者与消费者案例_多线程操作实例——生产者与消费者

    面对多线程学习生产者与消费者是最基本的实例 对于java后端开发的人员必须要掌握,还有考研考试计算机操作系统的同鞋. 下面是三个实例对于生产者与消费者的的例子,层层递进,逐步解决问题. 问题:生产者- ...

  8. kafka消费者如何读同一生产者消息_Kafka系列3:深入理解Kafka消费者

    上面两篇聊了Kafka概况和Kafka生产者,包含了Kafka的基本概念.设计原理.设计核心以及生产者的核心原理.本篇单独聊聊Kafka的消费者,包括如下内容:消费者和消费者组 如何创建消费者 如何消 ...

  9. 多生产者_【并发那些事】生产者消费者问题

    Step 1. 什么是生产者消费者问题 生产者消费者问题也叫有限缓冲问题,是多线程同步的一个最最最经典的问题.这个问题描述的场景是对于一个有固定大小的缓冲区,同时共享给两个线程去使用.而这两个线程会分 ...

最新文章

  1. 单击“登录”后,用户名和密码显示在地址栏中,不安全
  2. 机器学习笔记:激活函数
  3. vue 请求多个api_Vue 创建多人共享博客
  4. 更改linux子系统软件源为国内镜像
  5. 77种互联网盈利创新模式(3)
  6. WordPress响应式Alt_Blog主题 简约博客主题
  7. 比特币:一种点对点的电子现金系统
  8. oracle10g静默升级,Linux下静默安装,升级和删除Oracle10g客户端
  9. 蓝桥杯——阿尔法乘积
  10. android调用系统的自定义裁剪后得到的图片不清晰,使用MediaStore.EXTRA_OUTPUT获取缓存下的清晰图片...
  11. ERP系统测试用例设计
  12. FastStone Capture—屏幕录像
  13. html5期末大作业:基于HTML+CSS技术实现——传统手工艺术雕刻网站(3页)
  14. API 服务器健康状态自检
  15. 异常:The JSP specification requires that an attribute name is preceded by whitespace
  16. Linux下通过CCID协议与USB设备进行交互经验总结
  17. 2022年高压电工判断题及答案
  18. 一位想学习编程拯救他人的初中生
  19. leetcode学习打卡--572. 另一个树的子树(递归,二叉树遍历)
  20. Adabins:Transformer+单目深度估计

热门文章

  1. C语言Socket动态ajax网页,简单的ajax聊天网页 socket
  2. as本地仓库更改_Android Studio 之 Gradle与Project Structure详解
  3. mysql 查看主从_什么参数可以查看mysql主从复制是否正常
  4. editor修改样式 vue_vue-quill-editor的使用及个性化定制操作
  5. C++知识点9——函数重载,默认实参,内联函数
  6. rs232 距离_你知道RS232与RS485接口的区别吗?
  7. go context剖析之使用技巧
  8. Golang中time包
  9. 【leetcode】97. Interleaving String
  10. Webpack 4 api 了解与使用