关于线程内核对象句柄的简单问题

sanerersan 2011-01-01 03:42:34

在sdk中,使用CreateThread会返回一个线程句柄,然后进程内核对象句柄表是不是会增加两个句柄项,然后被调线程结束,就会将句柄表中其中一个与其关联的句柄项关闭,并将线程内核对象的引用计数减一。这时在主调线程中的句柄值还是有效的。所以还可以使用这个句柄进行一些操作。至少CloseHandle还是有效地。
上面我的理解对吗?
如果对的话,请看下面问题
在MFC中,使用AfxBeginThread创建一个线程。并将传回的CWinThread中的句柄保存在一个handle变量中。
我使用任务管理器观察,发现当被调线程结束时,应用程序会有两个句柄被关闭,然后再主调线程中使用CloseHandle将handle关闭,如果关闭成功,则会弹出一个消息框。但是我发现任务管理器中的句柄数量没有变,消息框也没有。。所以说在被调线程结束时将句柄表中的两个句柄项都删除的。
但是我看了下AfxBeginThread的代码,发现他只是CreateThread的简单封装,没有任何特殊之处,求解。
...全文
315 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
JINGRH 2011-10-05
  • 打赏
  • 举报
回复
楼主和2楼说的都不错。楼主遇到的问题原因 我认为是:一旦线程不再运行,系统中就没有别的线程能够处理该线程的句柄。 所以在使用的时候要在线程退出之前调用CloseHandle();
然而别的线程可以调用 GetExitcodeThread 来检查由 hThread 标识的线程是否已经终止运行。
Lactoferrin 2011-08-15
  • 打赏
  • 举报
回复
如果不理会PspCidTable
CreateThread会产生2个线程句柄,一个由CreateThread返回,另一个在csrss进程中
better0332 2011-08-15
  • 打赏
  • 举报
回复
PspCidTable(未导出)是指向 HANDLE_TABLE 指针的指针,这是一个特殊的句柄表,保存着
所有进程和线程对象的指针;PID(进程 ID)和 ThreadID(线程 ID)就是在这个句柄表中
的索引。它不属于任何进程,被称作内核句柄表。
sad_4978 2011-01-26
  • 打赏
  • 举报
回复
我觉得理解的不对。

记不清楚了。好像是Thread创建成功,引用计数器值是2。
Thread创建成功后,马上就可以跟着写一句CloseHandele().此时,计数器-1。
当线程结束,计数器再-1。

计数器为0,资源释放。

如果,感觉比较抽象,可以使用Spy++观察一下。
phikaa 2011-01-20
  • 打赏
  • 举报
回复
to 楼主: 一个线程只会有一个句柄。(如果是在想不通,就自己去windbg)
to ydbcsdn: 只有在你的线程中用到了C库里面的函数时,才会出现你说的情况。
nodiebirdcomeback 2011-01-12
  • 打赏
  • 举报
回复
CreateThread不是一定不安全的。
Yao-debo 2011-01-11
  • 打赏
  • 举报
回复
WINDOWS核心编程中对线程创建函数有讲解;
CreateThread是WINDOWS API, 不建议直接使用, 可能产生问题导致内存泄露;
而应该使用_begintthreadex, 这是一个Msvcr(微软运行时库)函数,可以理解成对CreateThread这个函数的修正.这个函数才是用户应该使用的;
而AfxBeginThread是对_begintthreadex的MFC封装;
关于句柄,代码中可以看到CWinThread有个成员变量m_bAutoDelete:
Specifies whether the CWinThread object should be automatically deleted at thread termination;
总的来说, _beginthreadex 这个函数最为放心, AfxBeginThread是为了方便使用CWinThread对象;
lin1270 2011-01-05
  • 打赏
  • 举报
回复
不知道楼主的代码如何写。。请试验以下代码:

DWROD WINAPI ThreadProc( LPVOID lpPara )
{
printf( "in thread\n" );
return 0;
}

VOID Test( void )
{
HANDLE hThread = ::CreateThread( ..., ThreadProc, ... );
WaitForSingleObject( hThread, INFINITE ); // 等待线程结束
CloseHandle( hThread );
}
QQ282881515 2011-01-05
  • 打赏
  • 举报
回复
楼主看问题很透彻! 顶
QQ282881515 2011-01-05
  • 打赏
  • 举报
回复
楼主看问题很透彻! 顶
sanerersan 2011-01-01
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wwgddx 的回复:]
不太清楚,帮顶,好像CreateThread会返回一个线程句柄,任务管理器中的句柄数量会增加1个,但并不会在线程退出的时候减少,需要手动CloseHandle将handle关闭才会减少,而且在CreateThread后立刻CloseHandle也不会影响创建线程的运行。
[/Quote]
并不是这样的,你调用createthread创建一个线程时,被调线程会打开一个句柄项,然后当createthread返回时,主调线程也会打开一个句柄项。所以应该会增加两个句柄值。这也是为什么你在createthread后调用closehandle不会影响线程的运行的原因。因为createthread后你的线程内核对象的引用计数是2,而不是1.所以你用closehandle会是引用计数便为1,但内核对象还是存在的。
wwgddx 2011-01-01
  • 打赏
  • 举报
回复
不太清楚,帮顶,好像CreateThread会返回一个线程句柄,任务管理器中的句柄数量会增加1个,但并不会在线程退出的时候减少,需要手动CloseHandle将handle关闭才会减少,而且在CreateThread后立刻CloseHandle也不会影响创建线程的运行。

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧