Windows学习(010)--内核对象(一)
程序员文章站
2022-06-03 18:19:09
...
内核对象概述
- Windows操作系统分为Ring3和Ring0层
- Ring3层是全开放的, 无监管的
- Ring0层是有监管的
- 是操作系统以及软件正在运行的地方
- 在软件运行的时候, 我们正真的操作都是在Ring0发生的
- 可通过WinAPI向Ring0层发送请求
- 当Ring0层检测到这是一个合理的请求时,内核对象会被Ring0层进行改变
- 通过句柄可以操作Ring0层指定的内核对象
- 但是句柄不代表Ring0层的某个具体的内核对象
- 句柄的值是不透明的, 无人知道它代表了什么意思
- 句柄是属于当前进程的
使用计数
- 每一个内核对象中, 都会有一个使用计数
- 内核对象是属于操作系统的
- 内核对象属于全局的,不同进程可以使用同一个内核对象
- 但是进程不能决定任何一个内核对象的生死
-
内核对象的生死却是由操作系统来决定
- 当内核对象没有意义的时候, 操作系统会清理内核对象以节约资源
- 但是Ring0和Ring3又无法交互
- 所以使用计数出现了
- 使用计数会在使用的时候+1, 在不使用的时候-1
- 当使用计数为0时, 操作系统会对内核对象进行回收
- 回收不是实时的, 是当系统空闲的时候, 优先来清理的
使用计数使得内核对象可以被多个进程所拥有, 并且能正确的释放
句柄表以及句柄的本质
- 先前也说过,我们可以通过句柄来操作内核对象,但句柄不代表内核对象本身,当一个句柄走出了一个进程,就毫无意义.
- 句柄是属于进程的,它存在于进程的句柄表中.通常创建一个内核对象的情景是,先在ring0中创建了一个内核对象,然后在进程句柄表中,找一个空白的索引的位置创建一个句柄,然后由此句柄中一个指针指向这个内核对象
句柄表存在的意义
- 在CloseHandle的时候,它会去进程的句柄表中找到索引对应的内核对象,找到后给内核对象发送一个使用计数递减的指令
- 当我们进程中的句柄在进程将要结束时,未被Closehandle,这样就回造成内核对象泄露.此时,句柄表就有了作用,它会根据其中的值,挨个CloseHandle
Signal状态
- 有Signal状态的内核对象
- 进程内核对象
- 线程内核对象
- 进程和线程内核对象在初始化的时候, Signal为FALSE
- 等到它们运行完成, Signal为TRUE
- 进程和线程内核对象就进入可受信(可接受信号)状态
- 进程和线程内核对象的Signal状态是系统来控制的
- 标准输入输出流对象
- 事件
- 互斥体
- 信号
- 可等待计时器
- 作业
- Signal的两种状态
- 可通知状态
- 不可通知状态
- 两种状态的改变可让系统来做,也可手动来做
WaitForSingleObject函数
- 函数原型
DWORD WINAPI WaitForSingleObject(
_In_ HANDLE hHandle,
_In_ DWORD dwMilliseconds
); - 此函数是用来等待一个内核对象的Signal,如果等待的内核对象是可通知状态,此函数则立马返回,否则,则会阻塞dwMillisecond毫秒的时间,阻塞会导致当前线程变为不可调度
- 返回值
- WAIT_TIMEOUT 等待超时
- WAIT_FAILED 等待失败, 需要调用GetLastError
- WAIT_OBJECT_0 等待完成, 指定的对象变为有信号了
- WAIT_ABANDONED 等待Mutex(互斥体)对象, 具体稍候了解
WaitForMultipleObjects函数
-
函数原型
DWORD WINAPI WaitForMultipleObjects( _In_ DWORD nCount, _In_ const HANDLE *lpHandles, _In_ BOOL bWaitAll, _In_ DWORD dwMilliseconds );
此函数是用来等待多一组内核对象,对参数设置不同,功能不同,总体功能类似WaitForSingleObject
- 参数
- nCount等待个数
- lpHandles等待数组的地址
- bWaitAll是否全部等待,当此参数为FALSE时,它只会等待最先为可通知状态的内核对象,等到了立即返回
- dwMilliseconds等待时间
- 返回值
- WAIT_OBJECT_0 到 WAIT_OBJECT_0 + nCount - 1也就是说, 返回值是一个范围
- 最大的返回是 WAIT_OBJECT_0 + nCount - 1
nCount是要等待的内核对象数量 - WAIT_ABANDONED_0 到 WAIT_ABANDONED_0 + nCount - 1
也是等待互斥体的, 稍候了解 - WAIT_TIMEOUT 等待超时
- WAIT_FAILED 等待失败, 需要调用GetLastError
上一篇: 下奶水果,这六种水果准妈妈们要注意!
下一篇: 彻底理解Python list切片原理
推荐阅读
-
PHP 面向对象程序设计(oop)学习笔记(一) - 抽象类、对象接口、instanceof 和契约式编程
-
Flask框架学习笔记(一)安装篇(windows安装与centos安装)
-
php学习笔记 php中面向对象三大特性之一[封装性]的应用
-
Windows核心编程:第9章 用内核对象进行线程同步
-
一步一步学习PHP(5) 类和对象
-
一步一步学习PHP(6) 面向对象
-
Ruby简洁学习笔记(一):字符串、数字、类和对象
-
大数据学习笔记【一】:Hadoop-3.1.2完全分布式环境搭建(Windows 10)
-
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
-
机器学习工具(一)——Windows 7 下安装 Tensorflow_CPU 版