大概是这样做的
先创建线程并保存该线程的句柄
每个线程完成以下操作:
在调test()前获得当前运行线程的句柄:和目标句柄(创建线程时返回的句柄)值是相同的
调用test(),test()中再次获取当前运行的线程句柄:和目标句柄(创建线程时返回的句柄)值不同了??这是为什么?#include <windows.h>
typedef DWORD (*task_type)(LPVOID lpParam);DWORD test_task1( LPVOID lpParam );
DWORD test_task2( LPVOID lpParam );
DWORD test_task3( LPVOID lpParam );task_type test_task[3] = {test_task1,test_task2,test_task3};
HANDLE h_save_true[3];
HANDLE h_event;
CRITICAL_SECTION cs_test;void myPrint(const char *frm, ...){    va_list vl;EnterCriticalSection(&cs_test);    va_start(vl, frm);    printf(frm, vl);    va_end(vl);LeaveCriticalSection(&cs_test);}
void test(void)
{
    HANDLE hProcessFalse = NULL;
    HANDLE hProcessTrue = NULL;
    HANDLE hThreadFalse = NULL;
    HANDLE hThreadTrue = NULL;hProcessFalse = GetCurrentProcess(  );
    hThreadFalse = GetCurrentThread(  );    DuplicateHandle( hProcessFalse, hThreadFalse, hProcessFalse, &hThreadTrue, 0, FALSE, DUPLICATE_SAME_ACCESS);
myPrint("current handle in test():%d\n",hThreadTrue);
}DWORD test_task1( LPVOID lpParam ) 
{
HANDLE hProcessFalse = NULL;
    HANDLE hProcessTrue = NULL;
    HANDLE hThreadFalse = NULL;
    HANDLE hThreadTrue = NULL;WaitForSingleObject(h_event,INFINITE);
    
myPrint("task1 start running\n");
myPrint("input para:%d\n",lpParam);hProcessFalse = GetCurrentProcess(  );
    hThreadFalse = GetCurrentThread(  );    DuplicateHandle( hProcessFalse, hThreadFalse, hProcessFalse, &hThreadTrue, 0, FALSE, DUPLICATE_SAME_ACCESS);myPrint("target handle:%d\n",h_save_true[0]);
    myPrint("actual handle:%d\n",hThreadTrue);test();
    
return 0;
}DWORD test_task2( LPVOID lpParam ) 
{
    HANDLE hProcessFalse = NULL;
    HANDLE hProcessTrue = NULL;
    HANDLE hThreadFalse = NULL;
    HANDLE hThreadTrue = NULL;    WaitForSingleObject(h_event,INFINITE);
    
    myPrint("task2 start running\n");
    myPrint("input para:%d\n",lpParam);    hProcessFalse = GetCurrentProcess(  );
    hThreadFalse = GetCurrentThread(  );    DuplicateHandle( hProcessFalse, hThreadFalse, hProcessFalse,     &hThreadTrue, 0, FALSE, DUPLICATE_SAME_ACCESS);myPrint("target handle:%d\n",h_save_true[0]);
    myPrint("actual handle:%d\n",hThreadTrue);test();return 0;
}DWORD test_task3( LPVOID lpParam ) 
{
HANDLE hProcessFalse = NULL;
    HANDLE hProcessTrue = NULL;
    HANDLE hThreadFalse = NULL;
    HANDLE hThreadTrue = NULL;WaitForSingleObject(h_event,INFINITE);
    
myPrint("task3 running\n");
hProcessFalse = GetCurrentProcess(  );
    hThreadFalse = GetCurrentThread(  );    DuplicateHandle( hProcessFalse, hThreadFalse, hProcessFalse, &hThreadTrue, 0, FALSE, DUPLICATE_SAME_ACCESS);myPrint("target handle:%d\n",h_save_true[0]);
    myPrint("actual handle:%d\n",hThreadTrue);test();return 0;
}
int main(int argc,char* argv[])
{
    DWORD i,rc;
int para[3];if (h_event) rc = CloseHandle(h_event);
CreateEvent(NULL,TRUE,0,"test_event");InitializeCriticalSection(&cs_test);for(i=0; i<3; i++)
{
para[i] = i;
        h_save_true[i] = CreateThread(NULL,256,(LPTHREAD_START_ROUTINE)test_task[i],&para[i],0,NULL);
}SetEvent(h_event);
WaitForMultipleObjects(3,h_save_true,TRUE,INFINITE);
    for(i=0; i<3; i++)
{
CloseHandle(h_save_true[i]);
}DeleteCriticalSection(&cs_test);
    return 0;}

解决方案 »

  1.   

    还是不太明白,执行test()时应该还是调test()的线程在运行呀,为什么此时得到的当前运行线程handle不是调test()的线程?ps:这就是个测试程序,看能不能得到当前运行的线程的真实句柄
      

  2.   

    发个精简版的代码,这次在线程中输出的handle和创建线程时返回的也不一样了,晕#include <windows.h>/*global vars*/
    HANDLE h_save_true;
    HANDLE h_event;
    CRITICAL_SECTION cs_test;/**/
    DWORD test_task( LPVOID lpParam );/*get current running thread handle*/
    void test(void)
    {
        HANDLE hThreadTrue = NULL;    DuplicateHandle(GetCurrentProcess(  ),
      GetCurrentThread(  ), 
               GetCurrentProcess(  ), 
      &hThreadTrue, 0, FALSE, DUPLICATE_SAME_ACCESS);

        printf("current handle in test():%d\n",hThreadTrue);
    }DWORD test_task( LPVOID lpParam ) 
    {
        HANDLE hThreadTrue = NULL;
        WaitForSingleObject(h_event,INFINITE);    EnterCriticalSection(&cs_test);
        
        printf("test task start running\n");    DuplicateHandle(GetCurrentProcess(  ), 
      GetCurrentThread(  ), 
      GetCurrentProcess(  ), 
               &hThreadTrue, 0, FALSE, DUPLICATE_SAME_ACCESS);    printf("target handle:%d\n",h_save_true);
        printf("actual handle:%d\n",hThreadTrue);    test();    LeaveCriticalSection(&cs_test);
        
        printf("test task1 end\n");
        return 0;
    }
    int main(int argc,char* argv[])
    {
        CreateEvent(NULL,TRUE,0,"test_event");
        InitializeCriticalSection(&cs_test);    h_save_true = CreateThread(NULL,256,
                                  (LPTHREAD_START_ROUTINE)test_task,
                                  0,0,NULL);
        printf("thread task1 handle:%d\n",h_save_true);    SetEvent(h_event);
        WaitForSingleObject(h_save_true,INFINITE);    CloseHandle(h_save_true);
        DeleteCriticalSection(&cs_test);    return 0;
    }
      

  3.   

    1. GetCurrentThread()返回的是一个伪句柄, 你希望的是两次DuplicateHandle返回的值完全一样? 那先把第一DuplicateHandle的Handle Close掉再看看
    2. 你不能假设操作系统在你的两次测试代码之间不抢占,因此最好是加上关键区,当然这个跟该问题关系不大
      

  4.   

    我原先的设想是 
    创建线程时返回的handle == 线程运行时通过duplicatehandle获得的真实句柄handle == 在test()中获得的当前运行线程的真实句柄handle现在程序运行的结果是:这三者都不相同ps:在获得当前运行线程的真实句柄时是加了关键区保护的:DWORD test_task( LPVOID lpParam ) 
    {
        HANDLE hThreadTrue = NULL;
        WaitForSingleObject(h_event,INFINITE);/*等待主线程激活事件*/    EnterCriticalSection(&cs_test);/*进入关键区*/
        
        printf("test task start running\n");    DuplicateHandle(GetCurrentProcess(  ), 
      GetCurrentThread(  ), 
      GetCurrentProcess(  ), 
               &hThreadTrue, 0, FALSE, DUPLICATE_SAME_ACCESS);    printf("target handle:%d\n",h_save_true);
        printf("actual handle:%d\n",hThreadTrue);    test();/**/    LeaveCriticalSection(&cs_test);/*离开关键区*/
        
        printf("test task1 end\n");
        return 0;
    }
      

  5.   

    那这就应该是DuplicateHandle的实现原理问题了
        从原理上来讲,操作系统根本保证对同一个内核对象DuplicateHandle出来的HANDLE值一样, 而只需要保证在进程句柄表里面,该HANDLE是唯一的, 并指向目标内核对象就行了. 而且实际上,该HANDLE也确实不应该一样, 因为DuplicateHandle出来的HANDLE都是要Close掉的, 一个HANDLE的Close不应该影响到其他的HANDLE
        <<windows 核心编程>>里也提过, 内核HANDLE值的实际意义并没有文档说明, 再加上你是从伪句柄Duplicate的,问题就更微妙了~
        像这种kernel方面的问题, 可能只有MS的人才能真正的回答你, 但是那样的话算不算泄密呢~ :(
      

  6.   

    打错了...
    是"操作系统根本不能保证对同一个内核对象DuplicateHandle出来的HANDLE值一样"