大家好,欢迎来到IT知识分享网。
一、 什么是内核对象?
我们知道进程、线程、文件、互斥、信号量这些都是操作系统级别的资源。我们在使用这些资源时,实际上都是由操作系统进行创建和管理的。操作系统为了管理这些资
源,会在其内部创建一个数据块,也可以理解为一个结构体对象。这个数据块就是内核对象。
二、 内核对象有哪两种状态?
内核对象的状态共有两种:signaled(有信号)状态和non-signaled(无信号)状态。以线程为例:当一个线程正在运行时,管理它内核对象处于non-signaled状态;而当线
程结束运行时,管理它的内核对象将处于signaled状态。
三、 内核对象的两种模式
Auto-reset模式 —— 当发生了某事件(如线程结束),内核对象进入signaled状态后,我们调用WaitForSingleObjec返回后,内核对象会自动进入non-signaled状态,内核对象的
这种模式就叫做auto-reset模式。
Manual-reset 模式 —— 当内核对象进入signaled状态后,WaitForSingleObjec返回,内核对象也不会自动进入non-signaled状态,除非我们手动将其设置为non-signaled状态,它
的的这种模式叫做manual-reset模式。
四、 获取内核对象状态的两个API
我们可利用WaitForSingleObject和WaitForMultipleObjects来获取内核对象的状态,如果这两个是阻塞函数,如果所监视的内核对象状态为signaled时,函数将会返回。下面
是WaitForSingleObject的函数原型:
DWORD WINAPI WaitForSingleObject( __in HANDLE hHandle, __in DWORD dwMilliseconds );
hHandle —— 表示要监视的线程、事件等内核对象管理的资源的Handle值。
dwMilliseconds —— 设置等待超时,单位是毫秒。如果设置成INFINITE表示一直等到内核对象状态变成signaled为止。
函数返回值 —— 若内核对象变成signaled状态,函数返回WAIT_OBJECT_0;若等待超时,函数返回WAIT_TIMEOUT
WaitForMultipleObjects的功能和WaitForSingleObject类似,只不过它可以同时等待多个内核对象状态的改变。其函数原型如下:
DWORD WINAPI WaitForMultipleObjects( __in DWORD nCount, __in const HANDLE *lpHandles, __in BOOL bWaitAll, __in DWORD dwMilliseconds );
nCount —— 等待的内核对象的个数。
lpHandles —— 存放内核对象句柄的数组的首地址。
bWaitAll —— 设置是否全部等待。若为True,表示所有的内核对象变成signaled状态后返回;若为False,表示只要有一个内核对象变成signaled 状态即返回。
dwMilliseconds —— 设置等待超时,单位是毫秒。如果设置成INFINITE表示一直等到内核对象状态变成signaled为止。
函数返回值 —— 若内核对象变成signaled状态,函数返回WAIT_OBJECT_0;若等待超时,函数返回WAIT_TIMEOUT
以下是使用WaitForMultipleObjects等待线程的实例。主要功能是启动两个线程,然后使用等待WaitForMultipleObjects两个线程结束,最后根据WaitForMultipleObjects的返回值打印输出线程是正常结束还是等待超时。
#include "stdafx.h" #include "windows.h" #include<process.h> unsigned WINAPI ThreadFunc1(void* args) { int i=0; while(1) { puts("ThreadFunc1 called ..."); if(++i==5) { puts("ThreadFunc1 Ended"); ExitThread(1); } Sleep(1000); } } unsigned WINAPI ThreadFunc2(void* args) { int i=0; while(1) { puts("ThreadFunc2 called ..."); if(++i==10) { puts("ThreadFunc2 Ended"); ExitThread(2); } Sleep(1000); } } int _tmain(int argc, _TCHAR* argv[]) { DWORD thredID1,thredID2; HANDLE handles[2]; handles[0]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc1,NULL,0,&thredID1); handles[1]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc2,NULL,0,&thredID2); DWORD dr = WaitForMultipleObjects(2,handles,true,INFINITE); if(dr==WAIT_OBJECT_0) { puts("两¢?个?内¨²核?对?象¨®都?进?入¨?signaled状Á¡ä态¬?。¡ê"); } else if(dr==WAIT_TIMEOUT) { puts("等̨¨待äy超?时º¡À。¡ê"); } return 0; }
main函数里,我们分别启动了两个线程,此时管理线程的内核对象将进入non-signaled状态。我们调用WaitForMultipleObjects等待线程结束进入signaled状态。当线程结束进入signaled状态后,WaitForMultipleObjects返回,开始执行其后面的语句。但是由于管理线程的内核对象不是Auto-Reset对象,这两个内核对象将一直保持signaled状态。
程序运行结果:
Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
git clone git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL46
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/152901.html