VC语言6.0程序设计从入门到精通-第68章
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
(1)CreateEvent
通过调用 Win32API 函数 CreateEvent 来创建或者打开一个事件对象 。如果调用成功,返
回事件对象的句柄,否则返回空。它的函数原型如下:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes;
BOOL bManualReset;
BOOL bInitialState;
LPCTSTR lpName
);
函数中主要参数的意义如下。
o lpEventAttributes :指向 SECURITY_ATTRIBUTES 结构的指针,它决定返回的句柄是
否可以被子进程继承。如果 lpEventAttributes 为空,则不能被继承。
·237 ·
…………………………………………………………Page 249……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
o bManualReset :指定创建一个手动重置事件或自动重置事件。如果为前者,必须调用
ResetEvent 手动设定状态为非激活状态。否则,当一个等待线程被释放后,系统会自
动设定对象的状态为非激活状态。
o bInitialState :指定对象的初始状态。
o lpName :事件对象的名称。
(2 )OpenEvent
函数 OpenEvent 可以打开一个存在的事件对象,允许多个进程打开同一个对象。如果调
用成功,返回事件对象的句柄。否则返回空。它的函数原型如下:
HANDLE OpenEvent(
DWORD dwDesiredAccess;
BOOL bInheritHandle;
LPCTSTR lpName
);
函数中主要参数的意义如下。
o dwDesiredAccess :指定如何操作对象。
o bInheritHandle :指定返回的句柄是否可以被继承。
o lpName :事件对象的名称。
(3 )SetEvent,ResetEvent 和 PulseEvent
如果需要修改事件句柄的状态,可以使用 SetEvent、ResetEvent 和 PulseEvent 。其中,
SetEvent 将事件句柄的状态改为激活状态,如果自动重置事件处于激活状态,在满足了等待
线程后,它可以被重置 。手动重置事件必须调用 ResetEvent 函数将事件对象重置为激活状态。
PulseEvent 函数用来向事件句柄发信号,并在所有的等待线程都被释放后,将事件句柄重置
为未激活状态。它们的返回值相同,如果调用成功,返回非 0 值,否则返回 0 。它们的函数
原型如下:
BOOL SetEvent(
HANDLE hEvent
);
BOOL ResetEvent(
HANDLE hEvent
);
BOOL PulseEvent(
HANDLE hEvent
);
函数中主要参数的意义如下。
o hEvent :事件对象的句柄。
如果不再使用句柄,可以调用 Win32API 函数 CloseHandle 关闭句柄。函数原型如下:
BOOL CloseHandle(
HANDLE hObject
);
·238 ·
…………………………………………………………Page 250……………………………………………………………
第 9 章 多线程
函数中主要参数的意义如下。
o hObject :对象的句柄。
(4 )CEvent
事件(Event )在 MFC 中的相应的类是 CEvent 。CEvent 的构造函数默认创建一个自动重
置的事件,而且处于未激发状态。它的成员函数及其作用如表 9…6 所示。
表 9…6 CEvent 类的成员函数
函数名称 作用
CEvent 构造函数,构造 CEvent 对象
SetEvent 启动事件对象,释放等待线程
PulseEvent 启动事件对象,释放等待线程,或者重置事件
对象为未激活状态
ResetEvent 设置事件对象为未激活状态
Unlock 释放事件对象
4 .互斥器(Mutex )
互斥器的功能与临界区相似。区别在于互斥器所花费的时间比临界区多很多,但是互斥
器是核心对象(后面介绍的 Event 和 Semaphore 也是核心对象),可以跨进程使用,而且等待
一个被锁住的互斥器可以设定 TIMEOUT,不会像临界区那样无法得知临界区的情况,一直
等待。
Win32 提供了创建互斥器 CreateMutex() ,打开互斥器 OpenMutex() ,释放互斥器
ReleaseMutex()等操作。
Mutex 的拥有权并非属于产生它的那个线程,而是属于最后对此 Mutex 进行等待操作
(
WaitForSingleObject )并且尚未进行 ReleaseMutex()操作的线程。线程拥有 Mutex 就好像进
入临界区一样,一次只能有一个线程拥有该 Mutex 。如果一个拥有 Mutex 的线程在返回之前
没有调用 ReleaseMutex() ,那么这个 Mutex 就被舍弃了。当其他线程等待这个 Mutex 时,仍
能返回,并得到一个 WAIT_ABANDONED_0 返回值,一个 Mutex 被舍弃是 Mutex 特有的功
能。下面详细介绍 Mutex 相关的函数。
(1)CreateMutex
函数 CreateMutex 用来创建或打开有名或无名的 Mutex 对象。如果调用成功,函数返回
创建后对象的句柄 。如果同名 Mutex 对象在创建之前就已经存在,则函数返回现有的对象的
句柄,并且 GetLastError 函数返回 ERROR_ALREADY_EXISTS 。否则返回创建的 Mutex 对
象句柄。如果调用失败,返回空值。它的函数原型如下:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes;
BOOL bInitialOwner;
LPCTSTR lpName
);
函数中主要参数的意义如下。
o lpMutexAttributes :指向 SECURITY_ATTRIBUTES 结构的指针,决定返回的句柄是否
可以被子进程继承。如果为空,则不能被继承。
·239 ·
…………………………………………………………Page 251……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
o bInitialOwner : 指 定 Mutex 对 象 的 初 始 拥 有 者 。 如 果 调 用 者 创 建 Mutex 并 且
bInitialOwner 为 TRUE,调用线程获得 Mutex 对象的拥有权。否则,调用线程不拥有
Mutex 的所有权。
o lpName :Mutex 对象的名称。字符串的最大长度为 MAX_PATH 个字符。字符串区分
大小写。如果 lpName 和一个现有的 Mutex 对象重名,函数需要对已有的对象有
MUTEX_ALL_ACCESS 的访问权。这种情况下,参数 bInitialOwner 被忽略,因为此
时它已经被已有的进程初始化。如果 lpMutexAttributes 非空,它决定句柄是否可以被
继承,但是它的安全描述成员被忽略。如果 lpName 为空,创建的 Mutex 对象没有名
称。
(2 )OpenMutex
函数 OpenMutex 用来打开一个存在的有名称的 Mutex 对象。如果调用成功,返回打开的
对象的句柄。反之则返回空值。它的函数原型如下:
HANDLE OpenMutex(
DWORD dwDesiredAccess;
BOOL bInheritHandle;
LPCTSTR lpName
);
函数主要参数的意义。
o dwDesiredAccess :指定希望对 Mutex 对象进行的访问类型。可以是下面值的组合:
· MUTEX_ALL_ACCESS :可以对 Mutex 对象进行所有访问。
· SYNCHRONIZE:允许任何等待函数获得 Mutex 对象的所有权。
o bInheritHandle :指定返回的句柄是否可以被继承。
o lpName :要打开的 Mutex 对象的名称。
(3 )ReleaseMutex
函数 ReleaseMutex 释放指定的 Mutex 对象的所有权。如果调用线程没有 Mutex 对象的所
有权,则说明调用失败。它的函数原型如下:
BOOL ReleaseMutex(
HANDLE hMutex
);
函数中主要参数的意义如下。
o hMutex :Mutex 对象的句柄。
(4 )CMutex
Mutex 在 MFC 中相应的类是 CMutex 。CMutex 通过构造函数创建一个互斥器对象。当
某个资源在一个时间只允许一个线程访问的时候,互斥器正好派上用场。
CMutex 只有一个构造函数 CMutex::CMutex,它的函数原型如下:
CMutex(
BOOL bInitiallyOwn = FALSE;
LPCTSTR lpszName = NULL;
LPSECURITY_ATTRIBUTES lpsaAttribute = NULL
·240 ·
…………………………………………………………Page 252……………………………………………………………
第 9 章 多线程
);
函数中主要参数的意义如下。
o bInitiallyOwn :指定创建线程是否在 CMutex 对象初始创建时访问互斥器控制的资源。
o lpszName :CMutex 对象的名称。如果有同名的互斥器存在,如果为空,�