Windows核心编程读书笔记4——线程(4)当前线程句柄与伪句柄
来源:互联网 发布:ps软件使用说明 编辑:程序博客网 时间:2024/06/06 02:20
在windows编程中,有时候我们会遇到需要传入作用对象句柄的函数,如GetThreadTimes(HANDLE hThread, ...)函数,允许我们获得句柄指定线程的运行时间。如果我们需要本线程的运行时间,那么只需要简单调用函数
GetCurrentThread()函数即可,其会返回当前线程的“伪”句柄。类似的,我们也有函数可以获得当前进程的句柄。
HANDLE GetCurrentThread(); //获得当前线程伪句柄HANDLE GetCurrentProcess(); //获取当前进程伪句柄
伪句柄与真实句柄
注意,之前我们说的通过GetCurrentThread与GetCurrentProcess函数获取的句柄,都是伪句柄。众所周知,每个进程都会有一个句柄表,来保存当前进程获取的内核对象句柄及其他信息。当进程获取一个内核对象时,操作系统会自动将该对象信息插入当前进程的句柄表,并返回类似于索引的句柄。因此每个内核对象的句柄在不同的进程中基本是不一样的。
但当我们调用GetCurrentThread()与GetCurrentProcess()时,其总是会返回值0xfffffffe(-2),0xffffffff(-1)。这就是所谓的伪句柄,它们并不反映真实的句柄表信息,仅用来作用于当前线程\进程本身。关于伪句柄,有以下几点要注意:
1、伪句柄仅限作用于当前线程\进程。超出了当前线程\进程便没有任何意义。
DWORD WINAPI childThread(PVOID pvParam){ HANDLE hThread = (HANDLE)pvParam; ... GetThreadTimes(hThread, ...);}int _tmain(int argc, _TCHAR* argv[]){ ... HANDLE hThread = GetCurrentThread(); CreateThread(nullptr, 0, childThread, (PVOID)hThread, 0, nullptr);... return 0;}
上面代码本意是通过子线程来获取主线程的运行时间,但由于传递的是伪句柄0xfffffffe(-2),因此在子线程中,其实会获取子线程的运行时间而非主线程。
2、伪句柄不用调用CloseHandle函数关闭
因为伪句柄不是真正的句柄,因此不需要CloseHandle来关闭。(即使调用了也没有任何影响,CloseHandle会返回errorcode ERROR_INVALID_HANDLE)。
伪句柄转换为真实句柄
像上面这种情况,有时候我们需要获取线程或进程的真实句柄,那么我们可以利用函数DuplicateHandle来获取。
BOOL WINAPI DuplicateHandle( _In_ HANDLE hSourceProcessHandle, _In_ HANDLE hSourceHandle, _In_ HANDLE hTargetProcessHandle, _Out_ LPHANDLE lpTargetHandle, _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwOptions);
该函数常用来从进程A中来复制一份内核对象句柄并使B进程可用。但我们可以灵活运用一下。我们可以将上面代码修改为
DWORD WINAPI childThread(PVOID pvParam){ HANDLE hThreadParent = (HANDLE)pvParam; ... GetThreadTimes(hThreadParent, ...); CloseHandle(hThreadParent); // 由于DuplicateHandle会增加句柄计数,因此不要忘记CloseHandle}int _tmain(int argc, _TCHAR* argv[]){ ... HANDLE hThreadParent = nullptr; // 通过DuplicateHandle获得线程的真实句柄。 DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), hThreadParent, 0, FALSE, DUPLICATE_SAME_ACCESS); CreateThread(nullptr, 0, childThread, (PVOID)hThreadParent, 0, nullptr);...; return 0;}需要注意的是,通过DuplicateHandle获取的真实句柄,需要CloseHandle进行关闭。同理,我们也可以获取进程的真实句柄。
- Windows核心编程读书笔记4——线程(4)当前线程句柄与伪句柄
- Windows核心编程---句柄和伪句柄
- 线程(进程)的句柄与伪句柄
- 进线程, 进线程句柄, 进线程ID, 句柄与ID间转换, 伪句柄, 伪句柄转为句柄
- 进线程, 进线程句柄, 进线程ID, 句柄与ID间转换, 伪句柄, 伪句柄转为句柄
- 获取当前线程句柄
- 线程与线程句柄
- 进程线程伪句柄转为真实句柄
- Windows核心编程学习笔记(10)--伪句柄
- 线程与socket句柄
- 《Windows核心编程》读书笔记——Windows线程池
- 读书笔记----《windows核心编程》第三章 内核对象1(句柄与安全性)
- 线程伪句柄转实句柄 内核对象共享
- 线程&进程(获取伪句柄 & 转为真实句柄)
- windows核心编程-句柄的获取与复制
- Windows核心编程笔记(三) 内核对象与句柄
- GetCurrentThread()获取当前线程句柄的陷阱
- Windows核心编程读书笔记1——线程(1)线程基础
- linux crontab 执行问题
- ListView滑动Item消失ListView,支持左右滑动位移,支持定义动画时间
- HM图片处理
- leetcode_155_Min Stack
- 自己动手写编译器之序
- Windows核心编程读书笔记4——线程(4)当前线程句柄与伪句柄
- javaweb-day06-1 (Servlet - Response - 输出中文、输出1、中文名字的文件下载、字符流读图片会导致数据丢失的剖析)
- Bridge桥接模式
- QQ透明皮肤:多层算法 一键适配各种背景
- 解决allegro 中OUT OF DATE SHAPES问题
- 1月份暨2014年年终工作总结
- 使用java mail 发送邮件
- 曾国藩论做人
- C++ vector反向迭代器的使用