《Win32多线程程序设计》学习笔记 第三章 快跑与等待
1.等待一个线程的结束
调用WaitForSingleObject()并放置一个“线程核心对象”作为参数,将使线程#1开始睡眠,知道线程#2结束为止。就像Sleep函数一样,WaitForSingleObject也有一个参数用来指定最长的等待时间。
DWORD WaitForSingleObject(
HANDLE hHandle, //等待对象的handle(代表一个核心对象).
DWORD dwMilliseconds /*等待的最长时间。时间终了,即使handle尚未成为激发状态,此函数还是要返回的。此值可以是0(代表立刻返回),也可以是INFINITE代表无穷等待。
*/
);
返回值:如果函数失败,则传回WAIT_FAILED。可调用GetLastError()取得更多信息。此函数成功有三个因素:
1.等待的目标(核心对象)变成激发状态。这种情况下返回值是WAIT_OBJECT_0.
2.核心对象变成激发状态之前,等待时间终了。返回值是WAIT_TIMEOUT.
3.如果一个拥有mutex(互斥器)的线程结束前没有释放mutex,则传回WAIT_ABANDONED.
HANDLE hHandle, //等待对象的handle(代表一个核心对象).
DWORD dwMilliseconds /*等待的最长时间。时间终了,即使handle尚未成为激发状态,此函数还是要返回的。此值可以是0(代表立刻返回),也可以是INFINITE代表无穷等待。
*/
);
返回值:如果函数失败,则传回WAIT_FAILED。可调用GetLastError()取得更多信息。此函数成功有三个因素:
1.等待的目标(核心对象)变成激发状态。这种情况下返回值是WAIT_OBJECT_0.
2.核心对象变成激发状态之前,等待时间终了。返回值是WAIT_TIMEOUT.
3.如果一个拥有mutex(互斥器)的线程结束前没有释放mutex,则传回WAIT_ABANDONED.
或得一个线程对象的handle之后,WaitForSingleObject()要求操作系统让线程#1睡觉,知道一下任何一种情况发生:
- 线程#2结束
- dwMilliseconds时间终了。该值系从函数调用后开始计算。
time-out的特殊用途,可以设为0,是你可以检查handle的状态并立刻返回。
WaitForSingleObject()可以面对许多handle工作,视你拥有的对象不同,操作系统等待的事情也不一样。一般来说,系统等待着一对象”被激发“。
可被WaitForSingleObject()使用的核心对象有2个状态:激发和未激发。 WaitForSingleObject()会在目标物变成激发状态时返回。
当线程正在执行时,线程对象处于未激发状态。当线程结束时,线程对象就被激发了。
核心对象的激发状态的意义
- Thread(线程):当线程结束时,线程对象即被激发。线程还在运行时,处于未激发状态。
- Process(进程):进程结束时,进程对象即被激发。进程还在运行时,未激发状态。
- Change Notification:当一个特定的磁盘子目录发生一件特别的变化时,此对象即被激发。此对象由FindFirstChangeNotification产生
- Console Input: 当console窗口的输入缓冲区有数据可用时,此对象处于激发状态。CreateFile和GetStdFile两个函数可以获得Console handle。
- Event: Event对象的状态直接受控于应用程序所使用的三个win32函数:SetEvent,PulseEvent,ResetEvent 。 CreateEvent和OpenEvent都可以传回一个event object handle。
- Mutex:如果mutex没有被任何线程拥有,他就是处于激发状态。一个一个等待mutex函数返回了,mutex就自动重置为未激发状态,CreateMutex和OpenMutex都可以获得一个mutex handle。
- Semaphore:类似于mutex,但其有计数器,可以约束其拥有者的个数。当计数器大于0时,处于激发状态,当等于0时,处于未激发状态。Create
2.等待多个对象
WaitForMultipleObjects()允许你在同一时间等待一个以上的对象。
DWORD WaitForMultipleObject(
DWORD nCount, //表示lphandles数组的元素个数
CONST HANDLE *lphandles, //指向一个有对象handles组成的数组。
BOOL bWaitAll, //如果为true,则表示所有的handles都必须激发,此函数才得以返回,否则,此函数将在任何一个handle激发时就返回。
DWORD dwMilliseconds //超时也返回,可为0,立即返回,INFINITE表示无穷等待。
);
返回值:
如果因时间终了而返回,则返回值是WAIT_TIMEOUT,类似WaitForSingleObject().
如果bWaitAll是TRUE,则返回值将是WAIT_OBJECT_0.
如果bWaitAll是FALSE,那么将返回值减去WAIT_OBJECT_0,就表示数组中的哪一个handle被激发了。
如果你等待的对象中有任何mutexes,那么返回值可能从WAIT_ABANDONED_0到WAIT_ABANDONED_0+nCount-1.
如果函数失败,则返回WAIT_FAILED。可以使用GetLastError找出失败原因。
DWORD nCount, //表示lphandles数组的元素个数
CONST HANDLE *lphandles, //指向一个有对象handles组成的数组。
BOOL bWaitAll, //如果为true,则表示所有的handles都必须激发,此函数才得以返回,否则,此函数将在任何一个handle激发时就返回。
DWORD dwMilliseconds //超时也返回,可为0,立即返回,INFINITE表示无穷等待。
);
返回值:
如果因时间终了而返回,则返回值是WAIT_TIMEOUT,类似WaitForSingleObject().
如果bWaitAll是TRUE,则返回值将是WAIT_OBJECT_0.
如果bWaitAll是FALSE,那么将返回值减去WAIT_OBJECT_0,就表示数组中的哪一个handle被激发了。
如果你等待的对象中有任何mutexes,那么返回值可能从WAIT_ABANDONED_0到WAIT_ABANDONED_0+nCount-1.
如果函数失败,则返回WAIT_FAILED。可以使用GetLastError找出失败原因。
3.在一个GUI程序中等待
MsgWaitForMultipleObjects()类似于WaitForMultipleObject(),但它会在”对象被激发“或”消息到达队列“时被唤醒而返回。
可以参考MSDN