WaitForSingleObject的作用[转]
Posted stephen-qin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WaitForSingleObject的作用[转]相关的知识,希望对你有一定的参考价值。
在多线程的情况下,有时候我们会希望等待某一线程完成了再继续做其他事情(比如主线程等待子线程结束完之后,自己再结束),要实现这个目的,可以使用Windows API函数WaitForSingleObject,或者WaitForMultipleObjects。这两个函数都会等待Object被标为有信号(signaled)时才返回的。
那么,信号是什么呢?首先我们可以假设这里存在一个文件和两个线程,我们规定这个文件同一时刻只能被一个线程所访问打开,那么我们的线程该如何知道这个文件现在有没有被别的线程访问呢?我们可以让线程等在一个死循环里,这个循环之一在尝试打开访问这个文件,直到能够打开为止;这样做虽然可以实现目的,但是死循环会占用大量的内存,所以windows就设置了信号量。信号量的作用简单理解就是一个标志位,在我们上述的问题中,这个文件就有一个信号量,初始时我们设信号量为FALSE,而只有当信号量为FALSE时线程才可以打开访问这个文件。那么,当第一个线程到达,信号量为FALSE,线程打开文件进行访问,并将信号量置为TRUE;在第一个线程在访问文件时,第二个线程到来,此时信号量仍未TRUE,所以第二个线程等待,这个等待的过程就是WaitForSingleObject。WaitForSingleObject在等待的过程中会进入一个非常高效的沉睡等待状态,只占用极少的CPU时间片。
WaitForSingleObject()
1. 格式
DWORD WaitForSingleObject( HANDLE hHandle, DWORDdwMilliseconds);
有两个参数,分别是THandle和Timeout(毫秒单位)。
如果想要等待一条线程,那么你需要指定线程的Handle,以及相应的Timeout时间。当然,如果你想无限等待下去,Timeout参数可以指定系统常量INFINITE。
2. 使用对象
它可以等待如下几种类型的对象:
Event,Mutex,Semaphore,Process,Thread
3. 返回类型
有三种返回类型:
WAIT_OBJECT_0, 表示等待的对象有信号(对线程来说,表示执行结束);
WAIT_TIMEOUT, 表示等待指定时间内,对象一直没有信号(线程没执行完);
WAIT_ABANDONED 表示对象有信号,但还是不能执行 一般是因为未获取到锁或其他原因
代码例如下:
1 // ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include "stdio.h" 6 #include "windows.h" 7 #include <iostream> 8 using namespace std; 9 10 int i = 0; 11 DWORD WINAPI FunProc(LPVOID lpParameter); 12 13 DWORD WINAPI FunProc(LPVOID lpParameter) 14 { 15 for (; i < 10; i++) 16 { 17 if (!(i % 10)) 18 cout << endl; 19 else 20 cout << i << endl; 21 } 22 return 0; 23 } 24 25 void main() 26 { 27 cout << i << endl; 28 HANDLE hThread; 29 hThread = CreateThread(NULL, 0, FunProc, NULL, 0, NULL); 30 DWORD dwRet = WaitForSingleObject(hThread, 1); 31 if (dwRet == WAIT_OBJECT_0) 32 { 33 cout<< "创建的线程执行结束" << endl; 34 } 35 if (dwRet == WAIT_TIMEOUT) 36 { 37 cout<< "等待超时" << endl; 38 } 39 if (dwRet == WAIT_ABANDONED) 40 { 41 cout<< "Abandoned" << endl; 42 } 43 CloseHandle(hThread); 44 system("pause"); 45 } 46
结果为:
这段代码中,首先在开始定义一个变量 i 为 0 ,然后在主函数中先将其输出便有了结果中第一行的 0 。
之后我们开启线程,进入线程函数FunProc,在FunProc中将 i++ 对 10 取余输出,一直到 i > 10 结束循环,线程结束,这是返回给WaitForSingleObject的结果为WAIT_OBJECT_0,表示线程正常结束,并将结果输出。
这其中WaitForSingleObject的效果就相当于一个关卡,只有返回给了WaitForSingleObject结果程序才能继续执行,当然线程不一定能正常执行结束,也可能会出现:
这就是未能等到线程结束信号量的等待时间就耗光了。我们也可以将WaitForSingleObject的第二个参数设置为 INFINITE,就可以一直等待。
线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回(那区别在哪呢?)
————————————————
版权声明:本文为CSDN博主「LL596214569」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/LL596214569/article/details/81088862
这个帖子里讲了使用超时时间的作用:
解决方案:
要解决等待并刷新,可以
重复
ret:= WaitforSingleObject(ProcessInfo.hProcess ,100); //等待
Application.ProcessMessages;
直到ret&lt; Wait_Timeout;
即每次只等待很短的时间,然后刷新界面,如果程序没有运行完成,则继续等待,否则
跳出。
另一篇文章,里面讲到了一个比较有用的功能:也讲了获取进程的一些方法
WaitForSingleObject的用法-(判断一个程序是否结束)
https://blog.csdn.net/iteye_3224/article/details/82123379
以上是关于WaitForSingleObject的作用[转]的主要内容,如果未能解决你的问题,请参考以下文章
WaitForSingleObject 和 WaitForMultipleObjects函数
CreateProcess .. WaitForSingleObject .. CloseHandle 调用的最佳 try..finally 位置