读书人

一些线程执行机制方面的有关问题

发布时间: 2012-03-29 12:53:12 作者: rapoo

一些线程执行机制方面的问题
问题1:

如果一个线程正在销毁的时候,其他线程又给它发了消息,这个时候,它会不会响应(处理)这些消息? 如果不处理,那消息队列中残存的消息会怎样?


问题2:
关于HANDLE的,在创建线程的时候会返回一个线程句柄。我看书上说这种核心对象用完是要释放,否则就像内存泄露一样,是一种浪费。 但是,如果我把HANDLE对象作为其它函数的参数 按值传递。那么,那些HANDLE的复制品是不是也都要使用CloseHandle来进行释放呢? 还是像指针一样,只要释放一次就可以了?(我看到HANDLE类型的定义就是一个VOID*,但是又看到书上说系统对于核心对象有引用计数,所以不知道该怎么办)

PS: 能不能创建完线程立刻把获得的句柄给释放掉? 我看侯捷的多线程程序设计中说 核心对象 不能等同于线程,有点完全独立的二者 的意思,用完就应该关闭它,既然我根本用不到它,是不是可以直接释放掉?


问题3:
一个程序开了很多子线程, 那么在程序退出的时候,主线程是不是会等所有的子线程等资源都回收完了,自己才退出(程序中我不会对子线程的生死做任何控制,不发送退出消息,创建完线程就让它自己运行)? 我对这块的处理机制不清楚


恳请赐教,能者多劳啊,呵呵 谢谢

[解决办法]
其实既然主程序都退出了,你也就不必太在意memory leak的问题了。
而且既然是主线程发出的退出要求,那么肯定是告诉子线程no more processing, 所以,消息不处理也罢,关于消息优先级,你可以参考一下windows核心编程
你的那个问题我刚才回答了,用队列容器类来管理消息块
[解决办法]
1,线程销毁的时候不会再处理任何消息,消息队列会被系统释放掉。
2,创建线程时候HANDLE释放只是为了其他进程更难找到你的这个线程,把钩子去掉而已. 线程HANDLE是始终存在的, 线程随时可以拿到自己的HANDLE
3,主线程退出的时候其它线程不会自动退出, 所以你需要通知其它线程退出并且等待它们结束以后退出主线程循环。当然强行退出整个进程并不是不可以,但是很可能没执行完的线程需要做的一些工作就没能彻底做完,发生问题

至于wm_quit, 这个消息一般都是UI线程来响应的, 线程里面必须存在消息循环才能够响应这个事件
否则你最好这么做:
while(1)
{
DWORD result = WaitForSingleObject(quitEvent, 0);
if (WAIT_OBJECT_0 == result) break;


......

}


-------------------------------------------------------
广告:VC/WinAPI 网络/多线程讨论 QQ群, 群号:41356711


[解决办法]
lx6636(水果萝卜), 你不用担心这个,那些消息会被Windows Manager扔掉,不会有内存泄露.

CreateThread之后Handle的RefCount不一定,但是CloseHandle以后变成0了。以下是个小实验:
我的程序:

#include <windows.h>

DWORD WINAPI ThreadProc(
LPVOID lpParameter)
{
return MessageBox(0, "thread ", "thread ", 0);
}


void main(int argc, char* argv[])
{
HANDLE h = CreateThread(NULL, 0, ThreadProc, 0, 0, 0);
__asm int 3; //debug here
CloseHandle(h);
MessageBox(0, "main ", "main ", 0);
}

这是Debug过程,直接用OS带的NTSD。

ntsd hello.exe
g
> heap!main+0x39:
> 004010b9 cc int 3
0:000> dv
argc = 1
Type information missing error for argv
h = 0x00000008
0:000> !handle
Handle 4
Type Key
Handle 8
Type Thread <==== 这个是我们的Thread Handle (8)

0:000> !handle 8 7
Handle 8
Type Thread
Attributes 0
GrantedAccess 0x1fffff:
Delete,ReadControl,WriteDac,WriteOwner,Synch
Terminate,Suspend,Alert,GetContext,SetContext,SetInfo,QueryInfo,SetToke
n,Impersonate,DirectImpersonate,\☼
HandleCount 3
PointerCount 5
Name <none>

注意HandleCount是3

再跟踪几步,过了CloseHandle。。。。

0:000> !handle
Handle 4
Type Key
Handle c
Type Directory
Handle 10
Type File

我们的Handle没了。 :( 所以一个CloseHandle就给把Handle给销毁了。

最后:
g

我们的两个MessageBox都出来了。 所以就是说Thread Handle没有了不影响Thread进行。

希望这个给大家印象深些。

另:
Process Quit了之后是谈不上内存泄露,因为Process Heap被回收了。

读书人网 >VC/MFC

热点推荐