WIN32 使用事件实现高效生产者消费者模型
WIN32 如何实现线程同步
WIN32 多线程编程中,可以使用临界区(CRITICAL_SECTION)和互斥体(MUTEX)实现线程互斥。但是对于同步问题,如果用上述两种方法实现,效率比较低,原因是它们必须通过条件判断来决定是否使用资源,CPU会不停的调度子线程。
于是,为了高效地解决同步问题,WINDOWS提供了事件机制(不是消息循环那个事件)。事件是一种内核对象,使用事件,我们可以完成临界区和互斥体的工作,而且事件可以设置初始通知状态,和是否自动重置通知状态,因此,事件使用起来更加自由,更重要的是,使用事件来实现线程同步不需要通过条件判断的方式,CPU不会给阻塞的线程分配时间片,这样效率更高。
下面用两个程序来说明,如何使用临界区和事件来实现生产者消费者模型,以及为什么使用事件效率更高。
事件实现(效率高)
/************************************************************************/
/*
使用事件实现生产者消费者
*/
/************************************************************************/#include "stdafx.h"
#include <WINDOWS.H>
#include <STDIO.H>HANDLE evtProduced, evtConsumed; // 生产/消费完成事件
int nProduct = 0; // 商品数量// 生产者线程
DWORD WINAPI ThreadProducer(LPVOID p)
{while (TRUE){// 由于 CreateEvent 的第二个参数是 FALSE,WaitForSingleObject 会自动将事件设置为未通知WaitForSingleObject(evtConsumed, INFINITE); // 等待消费者消费完成Sleep(2000); // 生产商品消耗时间nProduct += 5;printf("生产了5个商品,当前商品数量: %d\n", nProduct); SetEvent(evtProduced); // 通知消费者可以消费了}return 0;
}// 消费者线程
DWORD WINAPI ThreadConsumer(LPVOID p)
{while (TRUE){// 由于 CreateEvent 的第二个参数是 FALSE,WaitForSingleObject 会自动将事件设置为未通知WaitForSingleObject(evtProduced, INFINITE);while (nProduct > 0){nProduct--;printf("--------------消耗了1个商品,当前商品数量: %d\n", nProduct);Sleep(200);} SetEvent(evtConsumed); } return 0;
}int main(int argc, char* argv[])
{evtConsumed = CreateEvent(0, FALSE, TRUE, 0); // 初始状态:已消费(可以开始生产)evtProduced = CreateEvent(0, FALSE, FALSE, 0); // 初始状态:未生产(不可以消费) CreateThread(0,0,ThreadProducer,0,0,0);CreateThread(0,0,ThreadConsumer,0,0,0);getchar();return 0;
}
临界区实现(效率低)
/************************************************************************/
/*
使用临界区实现生产者消费者
*/
/************************************************************************/#include "stdafx.h"
#include <WINDOWS.H>
#include <STDIO.H>CRITICAL_SECTION cs; // 商品临界区锁锁
int nProduct = 0; // 商品数量DWORD WINAPI ThreadProducer(LPVOID p)
{while (TRUE){EnterCriticalSection(&cs);if (nProduct == 0){nProduct += 5;printf("生产了5个商品,当前商品数量: %d\n", nProduct);} LeaveCriticalSection(&cs);Sleep(2000);}return 0;
}DWORD WINAPI ThreadConsumer(LPVOID p)
{while (TRUE){ EnterCriticalSection(&cs);if (nProduct > 0){nProduct--;printf("--------------消耗了1个商品,当前商品数量: %d\n", nProduct);}LeaveCriticalSection(&cs);Sleep(200);}return 0;
}int main(int argc, char* argv[])
{InitializeCriticalSection(&cs); CreateThread(0,0,ThreadProducer,0,0,0);CreateThread(0,0,ThreadConsumer,0,0,0);Sleep(12345);return 0;
}
WIN32 使用事件实现高效生产者消费者模型相关推荐
- python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))...
昨日内容回顾 python中启动子进程 并发编程 并发 :多段程序看起来是同时运行的 ftp 网盘 不支持并发 socketserver 多进程 并发 异步 两个进程 分别做不同的事情 创建新进程 j ...
- Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型...
一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...
- 进程锁、事件、进程队列、进程间共享数据、生产者消费者模型
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 进程锁(Lock) 锁的基本概念 锁的基本用法 模拟12306抢票软件 信号量:Semaphone 概念 Semaphore ...
- 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)...
参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...
- 【Linux入门】多线程(线程概念、生产者消费者模型、消息队列、线程池)万字解说
目录 1️⃣线程概念 什么是线程 线程的优点 线程的缺点 线程异常 线程异常 Linux进程VS线程 2️⃣线程控制 创建线程 获取线程的id 线程终止 等待线程 线程分离 3️⃣线程互斥 进程线程间 ...
- Java多线程(十):BlockingQueue实现生产者消费者模型
BlockingQueue BlockingQueue.解决了多线程中,如何高效安全"传输"数据的问题.程序员无需关心什么时候阻塞线程,什么时候唤醒线程,该唤醒哪个线程. 方法介绍 ...
- pattern in java_Java里的生产者-消费者模型(Producer and Consumer Pattern in Java)
生产者-消费者模型是多线程问题里面的经典问题,也是面试的常见问题.有如下几个常见的实现方法: 1. wait()/notify() 2. lock & condition 3. Blockin ...
- 【C++】【设计模式之】生产者-消费者模型(理论讲解及实现)
一.什么是生产者-消费者模型 1.简单理解生产者-消费者模型 假设有两个进程(或线程)A.B和一个固定大小的缓冲区,A进程生产数据放入缓冲区,B进程从缓冲区中取出数据进行计算,这就是一个简单的生产者- ...
- golang实现生产者消费者模型
生产者消费者模型分析 操作系统中的经典模型,由若干个消费者和生产者,消费者消耗系统资源,生产者创造系统资源,资源的数量要保持在一个合理范围(小于数量上限,大约0).而消费者和生产者是通过并发或并行方式 ...
最新文章
- 批处理中setlocal enabledelayedexpansion
- python web 框架(八)-- Scrapy
- spring事务管理-注解配置aop事务(重点)
- 数学--数论--Hdu 5793 A Boring Question (打表+逆元)
- 【渝粤题库】陕西师范大学200511 美国文学
- 使用Notepad++自动排版代码
- 从里面学到的关于过去的经验 后篇
- ThinkPHP5.0 漏洞测试
- Android 系统(194)---Android实践 -- 设置系统日期时间和时区
- 2017年经历的那些灵异事件
- 清华大学黄民烈老师:本科生如何做出好的科研
- 震惊:selenium竟然不是自动化测试工具
- linux 下显示隐藏文件夹
- android 360短信拦截,Android版360卫士更威武
- Springboot中@autowired和@resource注解的区别
- 显示“Hello World”并转换为语音
- 设置金蝶kis记账王会计科目的教程
- FRED案例:矩形微透镜阵列
- 中国菜刀下载及基础使用教程
- Sygate Personal Firewall 5.6
热门文章
- HighNewTech:2019.08.08华为发布—面向2025十大趋势
- ML之DT:基于DT算法对泰坦尼克号乘客数据集进行二分类(是否获救)预测
- ML之SVM:基于sklearn的svm算法实现对支持向量的数据进行标注
- Crawler:爬虫基于urllib.request库实现获取指定网址上的所有图片
- 从去除噪点的说起,有OpenCV要什么PS?
- 人工智能的时代?未来已至?
- Jmeter Web 性能测试入门 (六):Jmeter 解析 response 并传递 value
- javascript闭包学习
- js中的arguments 参数
- Android 把第三方jar 打进java包