关于伪句柄和实句柄的问题
该问题从以下两段代码引出
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.   

    是核心编程上面的把?伪句柄和句柄都能代表一个核心对象,并且通过他们都能进行对核心对象的操作,比如CloseHandle等。但是伪句柄只是一个壳,他在线程间传递的时候,句柄所引用的东西是目标对象的,不是自身的。也就是说,在不同的线程中,他映射的对象不一样。而且伪句柄在传递过程中不会引起引用计数的增减。可以用DuplicateHandle将伪句柄转换成实句柄,同时源句柄引用计数加1。
      

  2.   

    伪句柄是一个壳,是什么意思呀?通过句柄不是就可以操作内核对象本身了吗?可是为什么伪句柄不能呢?即然不能那么HANDLE hParentThread = GetCurrentThread()返回的值是什么呢,使用DuplicateHandle()后hParaentThread的值又是什么呢?
      

  3.   

    为什么我在父线程和子线程中分别使用GetCurrentThread()返回的值都是一样的呀?(每次两个都是FFFFFFFE);
      

  4.   

    我的意思是:
    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,
      

  5.   

    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");
    }