Windows内核对象

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

等待单个内核对象 WaitForSingleObject
WaitForSingleObject(HANDLE hHandle,// 内 核对象句柄
DWORD dwMilliseconds)// 等待时间
WaitForSingleOjbect 函数可以等待一个内核对 象,直到该内核对象的状态 变为已通知状态,或者指定的等待时间已经到 了, 否则等待的线程处于等待 态,是不占用 CPU 的,当等待的时间到了, 函数返回 WAIT_TIMEOUT ,如 果是等待的对象变成已通知,则返回 WAIT_OBJECT_0 。
代码
跨越进程共享内核对象
..许多情况下,不同进程之间需要共享内核对 象。 ..文件映射对象能使你在同一机器的两个进程 之间共享数据块 ..互斥对象,信标和事件使不同进程中的线程 能够同步它们的连续运行 ..跨进程共享内核对象通过对象句柄的继承 性,命名对象等方式实现。
对象句柄的继承性
..只有当进程具有父子关系时,才能使用对象 句柄 的继承性 ..父进程创建子进程,为子进程赋予对父进程 内核 对象对象的访问权 ..内核对象句柄如果能被继承,必须在创建内 核对 象的时候必须把安全描述符的成员赋值: bInherritHandle=TRUE ..父进程创建子进程的时候 CreateProcess 函数 的 bInheritHandle 参数必须指定为 TRUE ..通常把内核对象句柄作为进程启动命令行参 数 (CreateProcess 的 pszCommondLine)传递 给子进程
等待多个内核对象 WaitForMultipleObjects 例 子程序
..±..ò: ..3ìADèòaμè′yN..Event,.òò....ù±.μ.μè′y·.ê.
ê.£oHAຫໍສະໝຸດ DLEg_ahThreadEvent[N];
// .aê..úo....óêy×é£.ê..è±.′′.¨o.
HANDLE
hThreadHandle=
CreateSemaphore(NULL, 0, TaskMain,
(LPVOID)this, 0,
&dwThreadID);
..±..ò: ′′.¨ê..tEvent.úo....ó
HANDLE hThreadHandle = CreateEvent(NULL,
..也可以一次等待多个内核对象,尤其在一个 线程等待多个 事件(Event)的情况下
..±..ò: DWORD WaitForMultipleObjects(
DWORD nCount, // μè′y.úo....óμ...êy
CONST
HANDLE*lpHandles,
//
′.′¢.úo....óμ.êy×é..
DWORD WaitForMultipleObjects(
DWORDnCount, // 等待内核对象的个数
CONST HANDLE*lpHandles, // 存 储 内 核 对
象的数组指针
BOOLfWaitAll, // 等到全部内核对象才退出
标志
DWORDdwMilliseconds);// TimeOutfWaitAll
例:
hThreadHandle= CreateThread(ThreadFunc, 0, 0, NULL);
DWORD
dwRet=
WaitForSingleObject(hThreadHandle, 500);
// 注:TimeOut 也可以指定为 INFINITE,表示 无限等待
if ( dwRet== WAIT_TIMEOUT) { …
// 创建失败,处理错误。
。。。。
}
完全的判断方式是
if (NULL == hThreadHandle ||
INVALID_HANDLE_AVLUE
==
hThreadHandle) {
// 创建失败,处理错误。
。。。。
}
内核对象创建-2 ..创建互斥量 Mutex 内核对象
HANDLE hThreadHandle= CreateMutex(NULL, 0, TaskMain,
内核对象创建-1 ..例创建 Windows 线程内核对象
HANDLE
hThreadHandle
=
CreateThread(NULL, 0, TaskMain,
(LPVOID)this, 0,
&dwThreadID);
判断这个线程是否创建成功,通常判断的方式 是
if (NULL == hThreadHandle ) {
内核对象的句柄
..内核对象的句柄,当调用一个创建内核对象 的函数时,该函数返回一个句柄,用来标志 这个内核对象。 ..这个句柄值是和进程密切相关的,只能在这 个进程中使用,如果在其他的进程中使用这 个句柄值操作句柄,会失败。 ..在这个进程中的其他线程,可以使用这个句 柄值
内核对象的使用计数
..内核对象是由内核拥有的,而不是由进程拥 有。如 果你的进程创建了一个内核对象的句柄,然后 你的 进程中止运行,那么,内核对象不一定会被销 毁。 ..内核对象的存在时间可以比创建该内核对象 的进程 长很多。 ..内核需要知道多少个进程正在使用某个内核 对象, 所以内核对象有一个使用计数。使用计数是内 核对 象常用的数据成员
(LPVOID)this, 0,
&dwThreadID);
..±..ò: ′′.¨D.o.á.Semaphore.úo....ó
HANDLE
hThreadHandle
=
CreateSemaphore(NULL, 0, TaskMain,
(LPVOID)this, 0,
..创建信号量 Semaphore 内核对象
} else if ( dwRet== WAIT_OBJECT_0 ) { …
} else {
// 错误处理
}
只有当 hThreadHandle 对应的线程函数返回的 时候,hThreadHandle 的状 态才变成已通知,WaitForSingleObject 函数才 能返回。
等待多个内核对象 WaitForMultipleObjects
内核对象和用户对象
..除了内核对象,应用程序也可以使用其他类 型的 对象。 ..菜单,窗口,鼠标光标,刷子和字体等属于 用户 对象或者 GDI 对象而不是内核对象 ..内核对象创建的函数中必须有安全描述符 (PSECURITY_ATTRIBUTES )作为参数, 用户 对象则不需要。 ..安 全 描 述 符 PSECURITY_ATTRIBUTES 描 述了谁创 建该内核对象,谁能够访问,谁无权访问等信 息。 ..大多数程序的安全描述符可以制定为 NULL
DWORD WINAP
线程 A 需要等待 N 种 Event,则一个基本的等
待方式是:
HANDLE g_ahThreadEvent[N]; // 这是内核对
象数组,事先被创建好
DWORD WINAPI ThreadFunc(PVOIDpParam)
// 线程的主函数
{ BOOL bRunFlag=TRUE; while(bRunFlag) { DWORD dwRet= WaitForMultipleObjects(N, g_ahThreadEvent,FALSE, INFINITE);
命名对象
..共享跨进程边界的内核对象的另外一种方法 是给 对象命名 ..CreateMutex,CreateEvent, CreateSemaphore,CreateWaitableTime,CreateFil eMapping 函数都有一个参数 pszName 作 为这个内核对象的名称 ..为 pszName 传递 NULL 参数,则系统创建匿 名的 内核对象 ..如果指定了同名的内核对象名称,则系统返 回同 一个内核对象(Handle 值不同,Handle 是属 于 进程的)
标志设置为 TRUE,表示只有等待的全部内核
对象都变成
已通知状态才返回,FALSE 表示有一个内核
对象变成已通知状态
就返回。 在 fWaitAll 为 FALSE 情况下,如果第一个内 核对象变成已通知状 态,则返回 WAIT_OBJECT_0, 如果第二个内 核对象变成已通知 状态,则返回 WAIT_OBJECT_1, 以此类推。
存取符号对象、事件对象、文件对象、文件映 象 对象、I/O 完成端口对象、作业对象、信箱对 象、 互斥对象、管道对象、进程对象、信标对象、 线 程对象和等待计时器对象
主要的内核对象
..进程(Process) ..线程(Thread) ..作业(Job) ..可等待定时器(Timer) ..文件(File) ..信标(Semphore,Event) ..互斥对象(Mutex) ..控制台输入(ConsoleInput,Output)
Switch(dwRet-WAIT_OBJECT_0){
case 0:// 线程要退出
bRunFlag=FALSE;
break;
case 1: processEvent1(); break; case N: processEvent2(); break; default: // 错误处理 } } // 做一些释放资源等的善后工作 } 注:这只是一个例子,并不是一个风格良好的
-Windows 内核对象
Window 多线程编程 ..在介绍 Window 多线程编程之前,
必须介绍一个重要的概念: Windows 内核对象
Windows 内核对象
..内核对象可以供系统和应用程序使用,来管 理各 种各样的资源,比如进程、线程、文件等。 ..作为 Windows 软件开发人员,需要经常创建、 打 开、和操作各种内核对象。系统也要创建和操 作 若干类型的内核对象, ..常见内核对象
进程的内核对象句柄表
..当一个进程初始化的时候,系统为他分配一 个句 柄表。该句柄表只维护内核对象,不用于用户 对 象或者 GDI 对象。 ..创建一个内核对象,系统返回一个内核对象 的句 柄,这个句柄实际上是在这个句柄表中的一个 索 引值。 ..在创建一个内核对象的时候,系统可能返回 一个 NULL(0),或者 INVALID_HANDLE_AVLUE(1),所以,不要单纯使用 INVALID_HANDLE_AVLUE 来判断一个内核 创 建函数的返回值是否有效。
这个函数会检查该内核对象的使用计数,如果 使 用计数是 0,该内核便从内存中销毁这个内核 对象。
(虽然系统会为您的遗漏做一些弥补的工作, 比如 在进程退出的时候扫描内核对象句柄表,关闭 那 些使用计数是 0 的内核对象,但是正常关闭一 个您 创建的内核对象,是称职的程序员所应该做 的。)
内核对象状态
..内核对象都有两种状态:已通知和未通知
包括 Thread,Event,Semaphore,Mutex 等内核 对象都有这两种状态。
..当一个线程等待一个未通知状态的内核对 象,该 线程将进入等待状态,线程不占用 CPU ..等待内核对象使用 WaitForSingleObject 函数 ..对于线程的内核对象,总是在未通知的状态 下创 建的,当线程终止运行的时候,线程的内核对 象 的状态变为已通知 ..这样的特点可以使我们知道一个线程是何时 终止 运行的,我们只需要等待线程的内核对象从未 通 知变成已通知,则可以知道线程退出了。
0, TaskMain,
(LPVOID)this, 0, &dwThread ..创建事件 Event 内核对象 HANDLE hThreadHandle= CreateEvent(NULL, 0, TaskMain, (LPVOID)this, 0, &dwThreadID);
关闭内核对象
..无论怎样创建内核对象,都要调用系统函数 CloseHandle 来结束对该对象的操作。 ..函数 BOOL CloseHandle(HANDLE hObj)
创建 Windows 内核对象
..使用 windows 内核函数来创建和操作内核 对象。每个内核对象只是内核创建的一个内 存块,并只能由该内核访问,该内存块是一 种树据结构,他的成员负责维护该对象的各 种信息。 ..例,一个进程对象有一个进程 ID、一个基 本优先级和退出代码,而文件对象有一个字 节位移,一个共享模式和一个打开模式。
命名对象例 ..进程 A 创建一个名字为”JeffMutex”的 Mutex
相关文档
最新文档