由于线程停工是操作系统的责任,当然操作系统也有责任让其他线程知道某个线程停工了。
Win32提供了一个名为WaitForSingleObject()的函数。他的第一个参数是个核心对象(如线程)的handle,为了方便讨论,我把即将等待的线程称为线程#1,把正在执行的线程称为线程#2。刚刚说的“线程核心对象”指的是线程#2。
调用WaitForSingleObject()并放置一个“线程核心对象”作为参数,将使线程#1开始睡眠,直到线程#2结束为止。
就像Sleep()函数一样,WaitForSingleObject()也有一个参数用来指定最长的等待时间。
DWORD WINAPI 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。
获得一个线程对象的handle之后,WaitForSingleObject()要求操作系统让线程#1睡觉,直到以下任何一种情况发生:
情况1)线程#2结束;
情况2)dwMilliseconds
时间结束(该值从函数调用后开始计算)。
由于操作系统持续追踪线程#2,即使线程#2失事或被强迫结束,WaitForSingleObject()仍然能够正常运作。
关于time-out,有一个特别重要
的用途,但很少人注意。设定time-out为0,使你能够检查handle的状态并立刻返回,没有片刻停留。如果handle已经准备好,这个函数会成功并传回WAIT_OBJECT_0。否则,这个函数立刻返回并传回WAIT_TIMEOUT。
另有其他一些理由使你需要设定time-out参数。最简单的理由是你不想被粘住,特别是你在调试的时候。如果你等待的线程陷入死循环,你或许可以根据此函数的返回值以及time-out获得一些警告。
WaitForSingleObject()可以面对许多中handles工作。不一定非得是线程handle。事实上,Win32大部分以HANDLE表示的对象都可以作为WaitForSingleObject的等待目标。
视你所拥有的对象而不同,操作系统等待的事情也不一样。形式上来讲,系统等待这一对象“被激发”。