VC6的几个同步对象有什么区别

来源:互联网 发布:暴风集团域名 编辑:程序博客网 时间:2024/05/27 14:13

转自:http://wmnmtm.blog.163.com/blog/static/38245714201074948282/?suggestedreading&wumii

几个同步类

class CSyncObject : public CObject

class CSemaphore : public CSyncObject

class CMutex : public CSyncObject

class CEvent : public CSyncObject

class CCriticalSection : public CSyncObject

class CSingleLock

class CMultiLock

 

//下面把单词解释一下:

sync:同步

object:对象

Semaphore:信号

Mutex:互斥

Event:事件

Critical:临界

Section:单元,区

Single:单一的

Lock:锁

Multi:Multimedia的缩写:多

 

=============================================================================

具体区别:

CEvent类(事件) 详细
CEvent 类提供了对事件的支持。事件告诉某一线程何时去执行某一给定的任务,从而使多个线程流平滑。例如在某些网络应用程序中,一个线程(记为A)负责监听通信端口,另一个线程(记为B)负责更新用户数据。通过使用CEvent类,线程A可以通知线程B何时更新用户数据,这样线程B可以尽快地更新用户数据。

每一个CEvent对象可以有两种状态:有信号状态(signaled)和无信号状态(nonsignaled)。线程监视位于其中(应用程序中)的CEvent类对象的状态,并在相应的时候采取相应的操作。


     在MFC中,CEvent类对象有两种类型,分别是所谓的人工事件和自动事件。对于自动事件,当其获得信号后,就会释放下一个可用的线程。一个自动 CEvent对象在被至少一个线程释放后会自动返回到无信号状态;而人工事件对象获得信号后,释放所有可利用线程,直到调用成员函数ReSetEvent ()将其设置为无信号状态时为止。注意,在创建CEvent类的对象时,默认创建的是自动事件。

CMutex类(互斥) 详细

CMutex类的对象代表“哑程(mutex)”——它为一个同步对象,允许多个线程共同访问同一资源。在仅仅一个线程被允许用于修改数据或其它被控制的资源时,哑程将变得非常有用。例如,给链接的列表增添一个结点就是只允许一个线程的过程。通过使用CMutex对象来控制链接列表,此时只有一个线程能够获得列表的访问权。 
  若要使用CMutex 对象,首先要构造一个所需的CMutex 对象。然后指定希望等待的哑程的名称,那么应用最初就将拥有它。可以在构造函数返回时,访问哑程。当你已经访问了被控制的资源后,再调用CSyncObject::Unlock函数。

CSemaphore类(信号量) 详细

一个CSemaphore类对象代表一个“信号”——一个同步对象,它允许有限数目的线程在一个或多个进程中访问同一个资源。一个CSemaphore对象保持了对当前访问某一指定资源的线程的计数。 
  对于一个只能支持有限数目用户的共享资源来说,CSemaphore是很有用的。 
  CSemaphore对象的当前计数是还可以允许的其它用户的数目。当这个计数达到零的时候,所有对这个由CSemaphore对象控制的资源的访问尝试都将被插入到一个系统队列中等待,直到它们的时间用完或计数值不再为零。这个被控制的资源可以同时接受访问的最大用户数目是在CSemaphore对象的构造期间被指定的。

CCriticalSection类(临界区) 详细 示例1

类CCriticalSection的对象表示一个“临界区”,它是一个用于同步的对象,同一时刻只允许一个线程存取资源或代码区。临界区在控制一次只有一个线程修改数据或其它的控制资源时非常有用。例如,在链表中增加一个结点就只允许一次一个线程进行。通过使用CCriticalSection对象来控制链表,就可以达到这个目的。 
  在运行性能比较重要而且资源不会跨进程使用时,建议采用临界区代替信号灯。

CSingleLock类 详细

CSingleLock没有基类。
一个CSingleLock类对象代表一种访问控制机制,这种机制用于控制在一个多线程程序中对一个资源的访问。为了使用同步类CSemaphore,CMutex,CCriticalSection,和CEvent。
你必须创建一个CSingleLock或CMultiLock对象来等待和释放这个同步对象
当你只需要每次等待一个对象时,可以使用CSingleLock。当在一个特别的时候你可以使用多个对象时,可以使用CMultiLock。

 CMultiLock 详细

CMultiLock类没有基类。
CMultiLock类的对象代表多线程程序中控制资源访问的访问控制机制。若为了使用同步类CSemaphore, CMutex, CCriticalSection和CEvent,可以创建CMultiLock或CSingleLock对象以等待或发行同步对象。若在某个特定的时间希望使用多个对象,就请使用CMultiLock。否则,当仅仅在某时需等候某一对象时,请使用CSingleLock。
若要使用CMultiLock 对象,首先要创建希望等待的同步对象的数组。

 

小结

*********************************************************************************************

 临界区:临界区是一种最简单的同步对象,它只可以在同一进程内部使用。它的作用是保证只有一个线程可以申请到该对象   

      互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。因为互斥量是跨进程的互斥量一旦被创建,就可以通过名字打开它。 
    互斥量(Mutex),信号灯(Semaphore),事件(Event)都可以被跨越进程使用来进行同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态则为无信号状态,在退出后为有信号状态。所以我们可以使用WaitForSingleObject来等待进程和线程退出。 
    通过互斥量我们可以指定资源被独占的方式使用,但如果有下面一种情况通过互斥量就无法处理,比如现在一位用户购买了一份三个并发访问许可的数据库系统,你的老板会要求你根据用户购买的访问许可数量来决定有多少个线程/进程能同时进行数据库操作,这时候如果利用互斥量就没有办法完成这个要求,信号灯对象可以说是一种资源计数器。 
    事件,前面讲的信号灯和互斥量可以保证资源被正常的分配和使用,而事件是用来通知其他进程/线程某件操作已经完成。

 

*********************************************************************************************

下面从源码中来体会一下它们之间的联系与区别: