关于伪句柄和实句柄的问题
该问题从以下两段代码引出
DWORD WINAPI ParentThread(PVOID pvParam)
{
HANDLE hParentThread = GetCurrentThread();
CreateThread(NULL, 0, ChildThread, (PVOID)hParentthread, 0, NULL);
.......
}DWORD WINAPI ChildThread(PVOID pvParam)
{
HANDLE hParentThread = (HANDLE)pvParam;
FILETIME ftCreationTime, ftExitTime, ftKernelTime, ftUserTime;
GetThreadTimes(hParentThread, &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime);
.......
}上面的代码的目的是让父线程给子线程传递一个线程句柄,以标识父线程。但是,父线程传递了一个伪句柄(通过GetCurrentThread()返回的是伪句柄), 而不是实句柄。当子线程开始运行时(GetThreadTimes(...)),得到的是自己的CPU时间,而不是父线程的CPU时间。(可是给GetThreadtimes传入的句柄参数却是父线程的句柄呀)书上说出现这种情况的原因是用GetCurrntThread()得到的是伪句柄。如果要改变这种情况可以用下面的代码。
DWORD WINAPI ParentThread(PVOID pvParam)
{
HANDLE hParentThread;
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hParentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
CreateThread(NULL, 0, ChildThread, (PVOID)hParentthread, 0, NULL);
.......
}DWORD WINAPI ChildThread(PVOID pvParam)
{
HANDLE hParentThread = (HANDLE)pvParam;
FILETIME ftCreationTime, ftExitTime, ftKernelTime, ftUserTime;
GetThreadTimes(hParentThread, &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime);
.......
}
这样就可以得到父线程的CPU时间,通过DuplicateHandle()就可以把伪句柄转换成实句柄.那么伪句柄和实句柄的关系是什么呀?能不能从本质上解释上面代码所产生的不同结果的原因呀?
该问题从以下两段代码引出
DWORD WINAPI ParentThread(PVOID pvParam)
{
HANDLE hParentThread = GetCurrentThread();
CreateThread(NULL, 0, ChildThread, (PVOID)hParentthread, 0, NULL);
.......
}DWORD WINAPI ChildThread(PVOID pvParam)
{
HANDLE hParentThread = (HANDLE)pvParam;
FILETIME ftCreationTime, ftExitTime, ftKernelTime, ftUserTime;
GetThreadTimes(hParentThread, &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime);
.......
}上面的代码的目的是让父线程给子线程传递一个线程句柄,以标识父线程。但是,父线程传递了一个伪句柄(通过GetCurrentThread()返回的是伪句柄), 而不是实句柄。当子线程开始运行时(GetThreadTimes(...)),得到的是自己的CPU时间,而不是父线程的CPU时间。(可是给GetThreadtimes传入的句柄参数却是父线程的句柄呀)书上说出现这种情况的原因是用GetCurrntThread()得到的是伪句柄。如果要改变这种情况可以用下面的代码。
DWORD WINAPI ParentThread(PVOID pvParam)
{
HANDLE hParentThread;
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hParentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
CreateThread(NULL, 0, ChildThread, (PVOID)hParentthread, 0, NULL);
.......
}DWORD WINAPI ChildThread(PVOID pvParam)
{
HANDLE hParentThread = (HANDLE)pvParam;
FILETIME ftCreationTime, ftExitTime, ftKernelTime, ftUserTime;
GetThreadTimes(hParentThread, &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime);
.......
}
这样就可以得到父线程的CPU时间,通过DuplicateHandle()就可以把伪句柄转换成实句柄.那么伪句柄和实句柄的关系是什么呀?能不能从本质上解释上面代码所产生的不同结果的原因呀?
1,伪句柄和实句柄一样能进行句柄操作,但是不会使引用计数增加。
#include <windows.h>
#include <iostream>using std::cout;
using std::endl;void main()
{
FILETIME ft_creationtime,ft_exittime,ft_kerneltime,ft_usrtime;
SYSTEMTIME st_creationtime,st_exittime,st_kerneltime,st_usrtime;
HANDLE hProcess=::GetCurrentProcess(); //得到伪句柄,但引用计数不变
if(hProcess!=NULL)
{ //下面用伪句柄作一些事情。
GetProcessTimes(hProcess,&ft_creationtime,&ft_exittime,
&ft_kerneltime,&ft_usrtime);
::FileTimeToSystemTime(&ft_creationtime,&st_creationtime);
::FileTimeToSystemTime(&ft_exittime,&st_exittime);
::FileTimeToSystemTime(&ft_kerneltime,&st_kerneltime);
::FileTimeToSystemTime(&ft_usrtime,&st_usrtime); cout<<"now output process time by milliseconds..."<<endl;
cout<<"process creation time:"<<st_creationtime.wMilliseconds<<endl;
cout<<"process exit time:"<<st_exittime.wMilliseconds<<endl;
cout<<"process kernel time:"<<st_kerneltime.wMilliseconds<<endl;
cout<<"process user mode time:"<<st_usrtime.wMilliseconds<<endl;
}
if(!CloseHandle(hProcess)) //关闭伪句柄,你会发现CloseHandle返回false
//因为CloseHandle的作用是使引用计数减1,但是伪句柄并不能使句柄计数增减。
{
cout<<"close handle error."<<endl;
}
system("pause");
}
2,
/*******************************************************************************
*这是伪句柄研究的第二个实例,他的结果出乎意料的和核心编程上所讲的相吻合。
*呵呵~ 1.8, 2004
*******************************************************************************/#include <windows.h>
//#include <iostream>
#include <stdio.h>
//using std::cout;
//using std::endl;DWORD WINAPI ThreadProc(PVOID p)
{
HANDLE hThread=(PVOID)p;
FILETIME ft_creationtime,ft_exittime,ft_kerneltime,ft_usrtime;
SYSTEMTIME st_creationtime,st_exittime,st_kerneltime,st_usrtime; if(hThread!=NULL)
{
GetThreadTimes(hThread,&ft_creationtime,&ft_exittime,
&ft_kerneltime,&ft_usrtime);
::FileTimeToSystemTime(&ft_creationtime,&st_creationtime);
::FileTimeToSystemTime(&ft_exittime,&st_exittime);
::FileTimeToSystemTime(&ft_kerneltime,&st_kerneltime);
::FileTimeToSystemTime(&ft_usrtime,&st_usrtime);
printf("now outputing child thread time with miniseconds.....\n");
printf("thread creation time:%d\n",(int)st_creationtime.wMilliseconds);
printf("thread exit time:%d\n",(int)st_exittime.wMilliseconds);
printf("thread kernel time:%d\n",(int)st_kerneltime.wMilliseconds);
printf("thread user mode time:%d\n",(int)st_usrtime.wMilliseconds);
}
return 0;
}
DWORD WINAPI ThreadProc2(PVOID p)
{
HANDLE hThread=(PVOID)p;
FILETIME ft_creationtime,ft_exittime,ft_kerneltime,ft_usrtime;
SYSTEMTIME st_creationtime,st_exittime,st_kerneltime,st_usrtime; if(hThread!=NULL)
{
GetThreadTimes(hThread,&ft_creationtime,&ft_exittime,
&ft_kerneltime,&ft_usrtime);
::FileTimeToSystemTime(&ft_creationtime,&st_creationtime);
::FileTimeToSystemTime(&ft_exittime,&st_exittime);
::FileTimeToSystemTime(&ft_kerneltime,&st_kerneltime);
::FileTimeToSystemTime(&ft_usrtime,&st_usrtime); printf("thread creation time:%d\n",(int)st_creationtime.wMilliseconds);
printf("thread exit time:%d\n",(int)st_exittime.wMilliseconds);
printf("thread kernel time:%d\n",(int)st_kerneltime.wMilliseconds);
printf("thread user mode time:%d\n",(int)st_usrtime.wMilliseconds);
}
return 0;
}void main()
{
FILETIME ft_creationtime,ft_exittime,ft_kerneltime,ft_usrtime;
SYSTEMTIME st_creationtime,st_exittime,st_kerneltime,st_usrtime;
HANDLE hThread=::GetCurrentThread();
if(hThread!=NULL)
{
GetThreadTimes(hThread,&ft_creationtime,&ft_exittime,
&ft_kerneltime,&ft_usrtime);
::FileTimeToSystemTime(&ft_creationtime,&st_creationtime);
::FileTimeToSystemTime(&ft_exittime,&st_exittime);
::FileTimeToSystemTime(&ft_kerneltime,&st_kerneltime);
::FileTimeToSystemTime(&ft_usrtime,&st_usrtime); printf("now outputing main thread time with miniseconds.....\n");
printf("thread creation time:%d\n",(int)st_creationtime.wMilliseconds);
printf("thread exit time:%d\n",(int)st_exittime.wMilliseconds);
printf("thread kernel time:%d\n",(int)st_kerneltime.wMilliseconds);
printf("thread user mode time:%d\n",(int)st_usrtime.wMilliseconds);
}
Sleep(1000); printf("now create child thread,and pass the main thread's handle to it.\n");
CreateThread(NULL,0,ThreadProc,(PVOID)hThread,0,NULL);
Sleep(1000);
HANDLE hThread2;
::DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),
&hThread2,0,FALSE,DUPLICATE_SAME_ACCESS);
if(hThread2!=NULL)
{
printf("create thread 2...\n");
CreateThread(NULL,0,ThreadProc2,(PVOID)hThread2,0,NULL);
} system("pause");
}