Win 32 多线程程序设计学习笔记之三:*WaitFor*Object函数
来源:互联网 发布:人工智能 人类 奴隶 编辑:程序博客网 时间:2024/05/21 16:56
1.等待一个线程的结束
DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);
参数
hHandle: 等待对象的 handle(代表一个核心对象)。在本例中,此为线程 handle。
dwMilliseconds :等待的最长时间。时间终了,即使 handle 尚未成为激发状态,此函数还是要返回。此值可以是 0
(代表立刻返回),也可以是 INFINITE 代表无穷等待。
返回值
如果函数失败,则传回WAIT_FAILED。这时候你可调用 GetLastError() 取得更多信息。此函数的成功有三个因素:
1. 等待的目标(核心对象)变成激发状态。这种情况下返回值将为WAIT_OBJECT_0。
2. 核心对象变成激发状态之前,等待时间终了。这种情况下返回值将为WAIT_TIMEOUT。
3. 如果一个拥有 mutex(互斥器)的线程结束前没有释放 mutex,则传回 WAIT_ABANDONED。
关于 time-out,有一个特别重要的用途,但很少被人注意。设定 time-out为 0,使你能够检查 handle 的状态并立刻返回,没有片刻停留。如果 handle已经备妥,那么这个函数会成功并传回 WAIT_OBJECT_0。否则,这个函数立刻返回并传回 WAIT_TIMEOUT。
WaitForSingleObject() 可以面对许多种 handles 工作,不一定要是本例所使用的线程 handle。事实上,Win32 中大部分以 HANDLE 表示的对象都能够作为 WaitForSingleObject() 的等待目标。视你所拥有的对象不同,操作系统等待的事情也不一样。形式上来说,系统等待着这一对象“被激发”。
可被 WaitForSingleObject() 使用的核心对象有两种状态:激发与未激发。WaitForSingleObject() 会在目标物变成激发状态时返回。事实上我们也几乎是以此作为对象激发与否的操作型定义。
当核心对象被激发时,会导致WaitForSingleObject() 醒来。稍后你将看到的其他 Wait() 函数也是如此。
当线程正在执行时,线程对象处于未激发状态。当线程结束时,线程对象就被激发了。因此,任何线程如果等待的是一个线程对象,将会在等待对象结束时被调用,因为当时线程对象自动变成激发状态。
数个线程可以同时等待相同的线程 handle。当该线程 handle 变成激发状态时,所有等待中的线程都会被唤醒。然而,其他核心对象可能只唤醒一个等待中的线程。到底是哪一种行为,得视你等待什么样的对象而定。某些对象的激发状态只能够维持到一个等待中的线程被唤醒,其他对象的激发状态则或许可以维持到它又被明白地重置(reset)。
2.核心对象激发状态的意义
- Thread*(线程) 当线程结束时,线程对象即被激发。当线程还在进行时, 则对象处于未激发状态。线程对象系由CreateThread() 或 CreateRemoteThread() 产生
- Process*(进程) 当进程结束时,进程对象即被激发。当进程还在进行时, 则对象处于未激发状态。CreateProcess() 或OpenProcess() 会传回一个进程对象的 handle
- Change Notification 当一个特定的磁盘子目录中发生一件特别的变化时,此对象即被激发。此对象系由 FindFirstChangeNotification()
- Console Input* 当 console 窗口的输入缓冲区中有数据可用时,此对象将处于激发状态。CreateFile() 和 GetStdFile() 两函数可以获得 console handle。
- Event* Event 对象的状态直接受控于应用程序所使用的三个Win32 函数:SetEvent()、PulseEvent()、ResetEvent()。CreateEvent() 和 OpenEvent() 都可以传回一个 event object handle。Event 对象的状态也可以被操作系统设定——如果使用于“overlapped”操作时
- Mutex* 如果 mutex 没有被任何线程拥有,它就是处于激发状态。一旦一个等待 mutex 的函数返回了,mutex 也就自动重置为未激发状态。CreateMutex() 和 OpenMutex()都可以获得一个 mutex handle。
- Semaphore* Semaphore 有点像 mutex,但它有个计数器,可以约束其拥有者(线程)的个数。当计数器内容大于0 时,semaphore 处于激发状态,当计数器内容等于0 时,semaphore 处于未激发状态。CreateSemaphore() 和OpenSemaphore() 可以传回一个 semaphore handl
DWORD WaitForMultipleObjects(DWORD nCount,CONST HANDLE *lpHandles,BOOL bWaitAll,DWORD dwMilliseconds);参数
nCount 表示 lpHandles 所指之 handles 数组的元素个数。最大容量是 MAXIMUM_WAIT_OBJECTS。
lpHandles 指向一个由对象 handles 所组成的数组。这些
handles 不需要为相同的类型。
bWaitAll 如果此为 TRUE,表示所有的 handles 都必须激发,此函数才得以返回。否则此函数将在任何一个
handle 激发时就返回。
dwMilliseconds 当该时间长度终了时,即使没有任何 handles 激发,此函数也会返回。此值可为 0,以便测试。亦
可指定为 INFINITE,表示无穷等待。
WaitForMultipleObjects() 的返回值有些复杂。
i 如果因时间终了而返回, 则返回值是 WAIT_TIMEOUT , 类似WaitForSingleObject()。
i 如果 bWaitAll 是 TRUE,那么返回值将是 WAIT_OBJECT_0。
i 如果 bWaitAll 是 FALSE,那么将返回值减去 WAIT_OBJECT_0,就表示数组中的哪一个 handle 被激发了。
i 如果你等待的对象中有任何 mutexes , 那么返回值可能从WAIT_ABANDONED_0 到 WAIT_ABANDONED_0 + nCount - 1。
i 如果函数失败, 它会传回 WAIT_FAILED。这时候你可以使用GetLastError() 找出失败的原因。
注 意 , handles 数组中的元素个数有上限, 绝对不能够超过MAXIMUM_WAIT_OBJECTS。在 Windows NT 3.x 和 4.0 中,其值为 64
while (GetMessage(&msg, NULL, 0, 0,))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GetMessage() 有点像是特殊版本的 WaitForSingleObject(),它等待消息而不是核心对象。一旦你调用 GetMessage(),除非有一个消息真正进入你的消息队列(message queue)之中,否则它不会返回。在此期间,Windows 就可以
自由地将 CPU 时间给予其他程序。GetMessage() 是 Win16 合作型多任务的关键。
“常常回到主消息循环”是十分重要的一件事。如果你没这么做,你的窗口就会停止重绘,你的程序菜单就不再有作用,用户不喜欢的事情则慢慢开始发生。问题是,如果你正使用 WaitForSingleObject()或WaitForMultipleObjects()等待某个对象被激发,你根本没有办法回到主消息循环中去。
DWORD MsgWaitForMultipleObjects(DWORD nCount,LPHANDLE pHandles,BOOL fWaitAll,DWORD dwMilliseconds,DWORD dwWakeMask);参数
dwWakeMask 欲观察的用户输入消息,可以是:
QS_ALLINPUT
QS_HOTKEY
QS_INPUT
QS_KEY
QS_MOUSE
QS_MOUSEBUTTON
QS_MOUSEMOVE
QS_PAINT
QS_POSTMESSAGE
QS_SENDMESSAGE
QS_TIMER
返回值
和 WaitForMultipleObjects() 相比较,MsgWaitForMultipleObjects() 有一些额外的返回值意义。为了表示“ 消息到达队列” , 返回值将是WAIT_OBJECT_0 + nCount。
- Win 32 多线程程序设计学习笔记之三:*WaitFor*Object函数
- Win 32 多线程程序设计学习笔记之二:线程
- Win 32 多线程程序设计学习笔记之五:终止线程
- Win 32 多线程程序设计学习笔记之四:同步控制(Synchronization)
- Win 32 多线程程序设计学习笔记之六:异步I/O(Overlapped I/O)
- Win 32 多线程程序设计学习笔记之一:基本概念
- 《win32多线程程序设计》学习笔记三
- win 32多线程程序设计读书笔记
- Object-C 学习笔记(三)---函数function
- POSIX多线程程序设计学习篇之三(条件变量)
- WIN32多线程程序设计学习笔记
- Win32API多线程程序设计学习笔记
- Linux多线程程序设计学习笔记
- 学习笔记 -- Win32 多线程程序设计
- IOS学习笔记之Object-C(三)
- WIN程序设计笔记
- 多线程学习笔记 三
- 多线程学习笔记三
- 汉诺塔
- 设计模式--观察者模式--UML
- suse 11下结合gitolite 配置git web
- IOS中的MVC设计模式理解
- CreateFile的FILE_FLAG_NO_BUFFERING 问题
- Win 32 多线程程序设计学习笔记之三:*WaitFor*Object函数
- TQ2440裸板---adc模数转换(详细注释)
- 快速排序算法---20世纪十大算法之一
- 手工设置Windows服务依赖关系
- iOS笔记:自带TableCell中imageView和textLabel位置调整(layoutSubviews)
- MFC 处理双击事件时屏蔽掉单击事件
- code inspector
- Dima and Trap Graph ------codeforces #214 div.2
- Jacob控制word文档拷贝段落内容