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 使用事件实现高效生产者消费者模型相关推荐

  1. python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))...

    昨日内容回顾 python中启动子进程 并发编程 并发 :多段程序看起来是同时运行的 ftp 网盘 不支持并发 socketserver 多进程 并发 异步 两个进程 分别做不同的事情 创建新进程 j ...

  2. Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型...

    一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...

  3. 进程锁、事件、进程队列、进程间共享数据、生产者消费者模型

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 进程锁(Lock) 锁的基本概念 锁的基本用法 模拟12306抢票软件 信号量:Semaphone 概念 Semaphore ...

  4. 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)...

    参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...

  5. 【Linux入门】多线程(线程概念、生产者消费者模型、消息队列、线程池)万字解说

    目录 1️⃣线程概念 什么是线程 线程的优点 线程的缺点 线程异常 线程异常 Linux进程VS线程 2️⃣线程控制 创建线程 获取线程的id 线程终止 等待线程 线程分离 3️⃣线程互斥 进程线程间 ...

  6. Java多线程(十):BlockingQueue实现生产者消费者模型

    BlockingQueue BlockingQueue.解决了多线程中,如何高效安全"传输"数据的问题.程序员无需关心什么时候阻塞线程,什么时候唤醒线程,该唤醒哪个线程. 方法介绍 ...

  7. pattern in java_Java里的生产者-消费者模型(Producer and Consumer Pattern in Java)

    生产者-消费者模型是多线程问题里面的经典问题,也是面试的常见问题.有如下几个常见的实现方法: 1. wait()/notify() 2. lock & condition 3. Blockin ...

  8. 【C++】【设计模式之】生产者-消费者模型(理论讲解及实现)

    一.什么是生产者-消费者模型 1.简单理解生产者-消费者模型 假设有两个进程(或线程)A.B和一个固定大小的缓冲区,A进程生产数据放入缓冲区,B进程从缓冲区中取出数据进行计算,这就是一个简单的生产者- ...

  9. golang实现生产者消费者模型

    生产者消费者模型分析 操作系统中的经典模型,由若干个消费者和生产者,消费者消耗系统资源,生产者创造系统资源,资源的数量要保持在一个合理范围(小于数量上限,大约0).而消费者和生产者是通过并发或并行方式 ...

最新文章

  1. 批处理中setlocal enabledelayedexpansion
  2. python web 框架(八)-- Scrapy
  3. spring事务管理-注解配置aop事务(重点)
  4. 数学--数论--Hdu 5793 A Boring Question (打表+逆元)
  5. 【渝粤题库】陕西师范大学200511 美国文学
  6. 使用Notepad++自动排版代码
  7. 从里面学到的关于过去的经验 后篇
  8. ThinkPHP5.0 漏洞测试
  9. Android 系统(194)---Android实践 -- 设置系统日期时间和时区
  10. 2017年经历的那些灵异事件
  11. 清华大学黄民烈老师:本科生如何做出好的科研
  12. 震惊:selenium竟然不是自动化测试工具
  13. linux 下显示隐藏文件夹
  14. android 360短信拦截,Android版360卫士更威武
  15. Springboot中@autowired和@resource注解的区别
  16. 显示“Hello World”并转换为语音
  17. 设置金蝶kis记账王会计科目的教程
  18. FRED案例:矩形微透镜阵列
  19. 中国菜刀下载及基础使用教程
  20. Sygate Personal Firewall 5.6

热门文章

  1. HighNewTech:2019.08.08华为发布—面向2025十大趋势
  2. ML之DT:基于DT算法对泰坦尼克号乘客数据集进行二分类(是否获救)预测
  3. ML之SVM:基于sklearn的svm算法实现对支持向量的数据进行标注
  4. Crawler:爬虫基于urllib.request库实现获取指定网址上的所有图片
  5. 从去除噪点的说起,有OpenCV要什么PS?
  6. 人工智能的时代?未来已至?
  7. Jmeter Web 性能测试入门 (六):Jmeter 解析 response 并传递 value
  8. javascript闭包学习
  9. js中的arguments 参数
  10. Android 把第三方jar 打进java包