CEvent,CSemaphore,CCriticalSection,CMutex
一、用CEvent实现线程同步
事件对象(Event)是最简单的同步对象,它包括有信号和无信号两种状态。在线程访问某一资源之前,也许需要等待某一事件的发生,这时用事件对象最合适。例如,只有在通信端口缓冲区收到数据后,监视线程才被激活。MFC中,CEvent类提供了对事件的支持。CEvent对象有两种类型:人工事件和自动事件。对于自动事件,当其获得信号后,就会释放下一个可用的线程。一个自动CEvent对象在被至少一个线程释放后会自动返回到无信号状态;而人工事件对象获得信号后,释放所有可利用线程,直到调用成员函数ReSetEvent()将其设置为无信号状态时为止。
在创建CEvent对象时,默认创建的是自动事件
CEvent类的构造函数原型如下:
CEvent(BOOL bInitia11y0wn=FALSE,//若bInitiallyOwn为TRUE,则使CMultilock类对象和CSingleLock类对象的线程可用;否则,要访问资源的线程必须等待。该参数的默认值为FALSEo
BOOL bManualReset = FALSE,//指定要创建的CEvent对象是属于手工事件还是自动事件。为TRUE,则为手工事件;否则为自动事件。该参数默认值为FALSE o
LPCTSTR lpszName=NULL,//指定要创建的事件对象的名,如果该事件对象将跨进程使用,则此参数不能为NULL。如果该参数和一个已经存在的CEvent对象相同,则该构造函数返回一个对这个已存在对象的引用;如果参数和一个已存在的非CEvent类的同步对象(如CMutex )相同,则对象创建失败。
LPSECURITY ATTRIBUTES lpsaAttribute=NULL)//指定要创建对象的安全属性,一般置为NULL o
在事件对象建成后,可以调用其成员函数来改变其状态。CEvent类的几个重要的成员函数
SetEvent:将CEvent类对象的状态设置为有信号状态,并且释放所有等待的线程;如果该事件是人工事件,则CEvent类对象保持为有信号状态,直到调用成员函数ResetEvent将其重新设为无信号状态时为止,这样该事件就可以释放多个线程;如果CEvent类对象为自动事件,则在SetEvent将事件设置为有信号状态后,CEvent类对象由系统自动重置为无信号状态,除非一个线程被释放
ResetEvent:该函数将事件的状态设置为无信号状态,并保持该状态直至SetEvent被调用时为止。由于自动事件是由系统自动重置,故自动事件不需要调用该函数
PulseEnent:发送一个事件脉冲,该函数完成一系列操作后才返回。对于自动事件,PulseEvent将事件设置为有信号状态,等待一个线程被释放,将事件重置为无信号状态,然后PulseEvent返回;对于人工事件,则将等待该事件的所有线程被释放,事件被自动重置为无信号状态,然后PulseEvent返回
一个CEvent对象在线程中被创建后,自动处于无信号状态,但在另一个线程中可以调用API函数WaitForSingleObject来监视其状态
二、CCriticalSection类实现线程同步
当多个线程访问一个独占性共享资源时,可以使用Critical Section(临界区)对象。任一时刻只有一个线程可以拥有临界区对象,拥有临界区的线程可以访问被保护起来的资源或代码段,其他希望进入临界区的线程将被挂起等待,直到拥有临界区的线程放弃临界区时为止。因此,任一时刻,只有一个线程可以拥有临界区对象,而只有拥有临界区对象的线程才可以访问受保护的数据。
MFC的CCriticalSection类提供了对临界区对象的支持,其用法也相当简单,有两种用法。
1.单独使用CCriticalSection对象
1)定义CCriticalSection类的一个全局对象,以使各个线程均能访问,例如:CCriticalSection criticalsection;//CCriticalSection类的构造函数只有一种形式,即不带任何参数
2)在访问需要保护的资源或代码之前,调用CCriticalSection类的成员函数Lock获得临界区对象。代码如下:critical section.Lock();
如果此时没有其他线程占有临界区对象,则调用Lock函数的线程获得临界区;否则,线程即将挂起,并放人到一个系统队列中等待,直到当前拥有临界区的线程释放了临界区时为止。
3)访问临界区完毕后,使用CCriticalSection的成员函数Unlock来释放临界区。代码如下:critical section.Unlock()
2.与同步辅助类CSingleLock或CMutiLock一起使用
下面以类CSingleLock为例,简单说明使用步骤:
1)定义CCriticalSection类的一个全局对象,格式如下:CCriticalSection critical_section;
2)在访问需要保护的资源之前,定义CSingleLock类的一个变量,并将critical_ section的地址传送给构造函数:CSingleLock singlelock(&critical_ section):
3)使用CSingleLock类的成员函数LOCk请求获得临界区。代码如下:singlelock.Lock();如果临界区已经被其他线程占用,则本线程挂起,等待临界区被释放。获得临界区对象后返回。
4)本线程中访问临界区中的共享资源后,调用CSingleLock类的成员函数Unlock来释放临界区:singlelock.Unlock();
三、CSemaphore类实现线程同步
使用信号量对象(Semaphore)也可以实现线程同步。信号量对象维护一个从0开始的计数,在计数值大于0时对象是有信号的,而在计数值为0时则是无信号的。通过使用信号量对象,可以限制对共享资源进行访问的线程数量。MFC中,CSemaphore类实现了对信号量对象的封装。具体来讲,CSemaphore的一个对象保存了对当前访问某一指定资源的线程的计数值,该计数值是当前还可以使用该资源的线程的数目。如果这个计数达到了零,则所有对这个CSemaphore类对象所控制的资源的访问尝试都被放入到一个队列中等待,直到超时或计数值不为零时为止。当一个线程访问了被保护的资源时,计数值减1;一个线程完成了对被控共享资源的访问时,计数值增to在CSemaphore类对象的构造函数中可以指定控制的资源可以同时接受访问的最大线程数,
构造函数原型如下。
CSemaphore
(LONG lInitialCount=1,//信号量对象的初始计数值,决定了在信号量对象建成后,能同时访问其中资源的最大线程数目。必须不小于0,不大于lMaxCount
LONG lMaxCount=1,//信号量对象计数值的最大值,该参数决定了同一时刻可访问由信号量保护的资源的线程最大数目
LPCTSTR pstrName=NULL,//指向要创建的信号量名字。如果该信号量跨进程使用,则该参数不能为空
LPSECURITY_ATTRIBUTES lpsaAttributes=NULL);
CSemaphore类一般也与线程同步辅助类CSingleLock或CMutiLock类结合使用。用法与CCriticalSection类似
CEvent,CSemaphore,CCriticalSection,CMutex的更多相关文章
- C++ 系列:多线程编程基础知识
Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...
- Windows多线程多任务设计初步(转)
Windows多线程多任务设计初步 [前言:]当前流行的Windows操作系统,它能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程 ...
- VC中利用多线程技术实现线程之间的通信
当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...
- MFC多线程
当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...
- 【C++】线程_beginthreadex参数说明
unsigned long _beginthreadex( void * _Security, //第1个参数:安全属性,NULL为默认安全属性 unsigned _StackSize, //第2个参 ...
- MFC【17-2】线程和线程同步化
17-2线程同步 Windows支持4中类型的同步对象,可以用过来同步由并发运行的线程执行的操作: 临界区 互斥量 事件 信号量 MFC在名为CCriticalSection\CMutex\CEven ...
- MFC 结束线程
在wtl工程中定义一个现成,如下:DWORD WINAPI ThreadFunc( LPVOID pParam ){if( g_pMainlg )g_pMainlg->DoEnumNetwork ...
- 如何创建一个简单的C++同步锁框架(译)
翻译自codeproject上面的一篇文章,题目是:如何创建一个简单的c++同步锁框架 目录 介绍 背景 临界区 & 互斥 & 信号 临界区 互斥 信号 更多信息 建立锁框架的目的 B ...
- CMutex、CCriticalSection、CSemaphore、CEvent、WaitForSingleObject 的小例子
一.CMutex CMutex mutex; mutex.Lock(); // 互斥的动作 // mutex.Unlock(); 二.CCriticalSection CCriticalSection ...
随机推荐
- 图数据库之Pregel
/* 版权声明:能够随意转载,转载时请务必标明文章原始出处和作者信息 .*/ author: 张俊林 节选自<大数据日知录:架构与算法>十四章.书籍文件夹在此 Pre ...
- 卓尼斯ZT-180评測
卓尼斯ZT-180评測 ——正在出差途中,用10”上网本发帖,没有拍照,且写得冲忙,不妥之处见谅. 一.採购 1.因外出旅游,不想带那台14"笔记本,所以想买一台平板电脑.当时,选择的 ...
- 最新的手机/移动设备jQuery插件
随着互联网的流行,移动网站开始急速增加,在2014年手机网站将会出现很多,所以手机网站是必须要学会制作的.手机网站不像桌面平台一样制作,否则会影响显示效果,目前大部分手机网站使用响应式设计技术,而且也 ...
- SQL————高级查询
高级查询 --连接查询 select * from 表1,表2 ————形成笛卡尔积 select * from 表1,表2 where 表1.主键=表2.外键 ————主外键位置可以互换 --jo ...
- Sql遍历数据库
Sql遍历数据库 set nocount on ) ) ) set @str='ad' Declare cur_Depart Cursor For select name,id from syscol ...
- 浏览器文档播放Shockwave Flash 插件问题
浏览器被提示shockwave flash crashed怎么办?在使用浏览器的时候经常被提示shockwave flash crashed,flash插件崩溃,网页就会出现一些无法显示的文件,下面绿 ...
- vc++ internet
1.用VC开发ActiveX文档服务器 MFC 4.2不支持开发ActiveX容器,但支持ActiveX服务器.只要在使用MFC AppWizard生成应用程序框架时选择支持Active Docume ...
- Android 自定义shape圆形按钮
Shape的属性: solid 描述:内部填充 属性:android:color 填充颜色 size 描述:大小 属性: android:width 宽 android:height 高 gradie ...
- EditText默认不弹出软键盘
#EditText默认不弹出软键盘# 网上关于EditText默认情况下不弹出软键盘,当手触摸到EditText,获取焦点时候,才会弹出软键盘,貌似都不能用,其实,在oncreate()方法中,加上 ...
- HTTP缓存缓存机制
http协议无状态,所以缓存设定从两方面考虑.客户端浏览器和服务器端. 浏览器端实现过期机制. 服务器端实现验证机制. 缓存机制. 为了减轻服务器负担,也减少网络传输数量.http1.0定义了Expi ...