VC++线程同步解析
2012-08-10 14:21:29 来源:WEB开发网在MFC 中,通过CSemaphore 类对信号量作了表述。该类只具有一个构造函数,可以构造一个信号量对象,并对初始资源计数、最大资源计数、对象名和安全属性等进行初始化,其原型如下:
CSemaphore( LONG lInitialCount = 1, LONG lMaxCount = 1, LPCTSTR pstrName = NULL, LPSECURITY_ATTRIBUTES lpsaAttributes = NULL );
在构造了CSemaphore 类对象后,任何一个访问受保护共享资源的线程都必须通过CSemaphore 从父类CSyncObject 类继承得到的Lock()和UnLock()成员函数来访问或释放CSemaphore 对象。与前面介绍的几种通过MFC 类保持线程同步的方法类似,通过CSemaphore 类也可以将前面的线程同步代码进行改写,这两种使用信号量的线程同步方法无论是在实现原理上还是从实现结果上都是完全一致的。下面给出经MFC 改写后的信号量线程同步代码:
// MFC 信号量类对象
CSemaphore g_clsSemaphore(2, 2);
UINT ThreadProc24(LPVOID pParam)
{
// 试图进入信号量关口
g_clsSemaphore.Lock();
// 线程任务处理
AfxMessageBox("线程一正在执行!");
// 释放信号量计数
g_clsSemaphore.Unlock();
return 0;
}
UINT ThreadProc25(LPVOID pParam)
{
// 试图进入信号量关口
g_clsSemaphore.Lock();
// 线程任务处理
AfxMessageBox("线程二正在执行!");
// 释放信号量计数
g_clsSemaphore.Unlock();
return 0;
}
UINT ThreadProc26(LPVOID pParam)
{
// 试图进入信号量关口
g_clsSemaphore.Lock();
// 线程任务处理
AfxMessageBox("线程三正在执行!");
// 释放信号量计数
g_clsSemaphore.Unlock();
return 0;
}
……
void CSample08View::OnSemaphoreMfc()
{
// 开启线程
AfxBeginThread(ThreadProc24, NULL);
AfxBeginThread(ThreadProc25, NULL);
AfxBeginThread(ThreadProc26, NULL);
}
互斥内核对象
互斥(Mutex)是一种用途非常广泛的内核对象。能够保证多个线程对同一共享资源的互斥访问。同临界区有些类似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。与其他几种内核对象不同,互斥对象在操作系统中拥有特殊代码,并由操作系统来管理,操作系统甚至还允许其进行一些其他内核对象所不能进行的非常规操作。为便于理解,可参照图6 给出的互斥内核对象的工作模型:
以互斥内核对象来保持线程同步可能用到的函数主要有CreateMutex()、OpenMutex()、ReleaseMutex()、WaitForSingleObject()和WaitForMultipleObjects()等。
在使用互斥对象前,首先要通过CreateMutex()或OpenMutex()创建或打开一个互斥对
象。CreateMutex()函数原型为:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 安全属性指针
BOOL bInitialOwner, // 初始拥有者
LPCTSTR lpName // 互斥对象名
);
参数bInitialOwner 主要用来控制互斥对象的初始状态。一般多将其设置为FALSE,以表
明互斥对象在创建时并没有为任何线程所占有。如果在创建互斥对象时指定了对象名,那么可以
在本进程其他地方或是在其他进程通过OpenMutex()函数得到此互斥对象的句柄。
OpenMutex()函数原型为:
HANDLE OpenMutex(
更多精彩
赞助商链接