大概是这样做的
先创建线程并保存该线程的句柄
每个线程完成以下操作:
在调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],¶[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;}
先创建线程并保存该线程的句柄
每个线程完成以下操作:
在调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],¶[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;}
解决方案 »
- 渐变填充的问题
- VC/MFC版主删帖记录处
- 请问大家现在能上codeproject吗??
- 寻找快速捕获屏幕的方法
- 关于文件保存读出问题--十万火急,在线等待,重分相谢!
- 急!解决此问题者奉送200分!!! up有分!!
- 调用OpenProcess时,系统会发送哪个消息?用哪个hook拦截?
- 客户端发送的命令,服务器端为何接受不到?
- **************很好拿的分,哪儿可以下载3d素材?大家进来帮我,我帮我女友。****************
- (+)(+)~ 请问:如何创建不带数据库连接的报表?因为创建新报表时候,水晶报表会问我连接数据库的名称,但是我想绕开这个环节,因为--我用水晶
- 不通过鼠标位置控制窗口控件??
- 如何捕获一个对话框程序的内部消息
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;
}
2. 你不能假设操作系统在你的两次测试代码之间不抢占,因此最好是加上关键区,当然这个跟该问题关系不大
创建线程时返回的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;
}
从原理上来讲,操作系统根本保证对同一个内核对象DuplicateHandle出来的HANDLE值一样, 而只需要保证在进程句柄表里面,该HANDLE是唯一的, 并指向目标内核对象就行了. 而且实际上,该HANDLE也确实不应该一样, 因为DuplicateHandle出来的HANDLE都是要Close掉的, 一个HANDLE的Close不应该影响到其他的HANDLE
<<windows 核心编程>>里也提过, 内核HANDLE值的实际意义并没有文档说明, 再加上你是从伪句柄Duplicate的,问题就更微妙了~
像这种kernel方面的问题, 可能只有MS的人才能真正的回答你, 但是那样的话算不算泄密呢~ :(
是"操作系统根本不能保证对同一个内核对象DuplicateHandle出来的HANDLE值一样"