现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

详说MFC的同步对象与同步访问对象

2013-07-27 23:43 工业·编程 ⁄ 共 1721字 ⁄ 字号 暂无评论

在多线程的情况下,如果存在多个线程要使用同一个资源的情况时,则需要在线程之间进行协调(同步)才能使程序完成预定的工作,而不会出现灾难性的冲突。

MFC 提供的多线程类分为两类:同步对象CSyncObjectCSemaphoreCMutexCCriticalSectionCEvent )和同步访问对象CMultiLockCSingleLock )。

当必须控制对资源的访问以确保资源的完整性时,使用同步类。同步访问类用于获取对这些资源的访问权。本主题介绍各个类的适用情况。
若要确定应使用的同步类,请询问以下一系列问题:

  1. 应用程序必须等到发生某事才能访问资源(例如,在将数据写入文件之前,必须先从通信端口接收它)吗?
    如果是,请使用 CEvent

  2. 同一应用程序内一个以上的线程可以同时访问此资源(例如,应用程序允许在同一文档上最多同时打开五个带有视图的窗口)吗?
    如果是,请使用 CSemaphore

  3. 可以有一个以上的应用程序使用此资源(例如,资源在 DLL 中)吗?
    如果是,请使用 CMutex

    如果不是,请使用 CCriticalSection

从不直接使用 CSyncObject 。它是其他四个同步类的基类。

同步访问对象的作用,为了统一方便丰富的调用接口,并且当超过使用范围后,就会自动析构调用Unlock (),防止忘记解锁。

    若为了使用同步类CSemaphore, CMutex, CCriticalSection和CEvent,可以创建CMultiLock或CSingleLock对象以等待或释放同步对象。若在某个特定的时间希望使用多个对象,就请使用CMultiLock 。否则,当仅仅在某时需等候某一对象时,请使用CSingleLock 。要使用一个CSingleLock 对象,在被控制资源的类中的一个成员函数内部调用CSingleLock 的构造函数。然后调用ISLock成员函数来确定这个资源是否可用。如果资源是可用的,则继续该成员函数的其余部分。如果资源不能使用,可以在一个指定的时间内等待资源被释放,或者是返回失败。在使用完资源后,如果CSingleLock 对象要被再次使用,可以调用Unlock函数,或者销毁CSingleLock 对象。

    CSingleLock 对象需要有一个从CSyncObject 派生的对象存在。这通常是一个被控制资源的类的数据成员。若要使用CMultiLock 对象,首先要创建希望等待的同步对象的数组。然后,调用被控制的资源类成员函数内的CMultiLock对象的构造函数。其后调用Lock 成员函数来决定资源是否为有效资源(被标记)。若有,就继续进行该成员函数的操作。否则,要么等待一定的时间,等资源被释放,要么返回失败。在资源完全使用后,要么当再一次使用CMultiLock 对象调用Unlock 函数,要么允许销毁CMultiLock 对象。CMultiLock 对象在线程有大量响应的CEvent 对象时非常有用。首先创建一个包含所有CEvent 指针的数组,然后调用Lock 函数。这将导致线程等待到某个事件被标记。

使用CSingleLock 的示例:

// m_CritSection is a data member (of type CCriticalSection) 
// of an existing class that implements the resource being shared. 
// Relate the synchronization object (m_CritSection) with 
// our CSingleLock object. 
CSingleLock singleLock(&m_CritSection); 
singleLock.Lock();  // Attempt to lock the shared resource 
if  (singleLock.IsLocked())  // Resource has been locked 

//...use the shared resource... 
// Now that we are finished, 
// unlock the resource for others. 
    singleLock.Unlock(); 
}

给我留言

留言无头像?