咋说呢,一直以来虽然知道_beginthreadex
比较好。但是想起55用CreateThread
,还是有点余悸。
先看段原话:
有些CRT的函数象malloc(), fopen(), _open(), strtok(), ctime(), 或localtime()
等函数需要专门的线程局部存储的数据块,
这个数据块通常需要在创建线程的时候就建立,如果使用CreateThread
,这个数据块就没有建立,然后会怎样呢?
在这样的线程中还是可以使用这些函数而且没有出错,实际上函数发现这个数据块的指针为空时,会自己建立一个,
然后将其与线程联系在一起,这意味着如果你用CreateThread
来创建线程,然后使用这样的函数,
会有一块内存在不知不觉中创建,遗憾的是,这些函数并不将其删除,而CreateThread
和ExitThread
也无法知道这件事,
于是就会有Memory Leak,在线程频繁启动的软件中(比如某些服务器软件),迟早会让系统的内存资源耗尽!
说白了:如果多线程里面有CRT函数,最好使用_beginthread
_beginthreadex
AfxBeginThread
(这个函数内部调用_beginthreadex
创建处理的CWinThread
专门的UI线程,可以通过发送接收message)
上面四个线程都有相应的ExitThread或_endthread
;当然这些函数必须放入线程函数中。
共同点:
共同的毛病1:
虽然:在线程被创建成功后,都可以用WaitForSingleObject( hThread, INFINITE );
来等待线程结束。
但是这是不准的:一些begin
函数本身就有CloseHandle
了(如:_beginthread
),再加上一些代码的CloseHandle
,
所以无法正确知道线程的计数到底是在哪个时候被置为0,而且被置为0也不一定会是线程退出。
再说执行完线程函数后,beging
函数本身有许多代码要执行。
也就是说,最好不要这么等待线程结束,最好给个事件、原子等放在线程函数末尾,来判断线程是否结束。
共同的毛病2:
如果在线程函数中调用退出函数,是会立即退出的。
也就是说连执行线程函数中,定义类的析构函数都来不及,就会直接退出线程返回,
如果那个类有析构有内存释放的话就糟糕了,会出现内存泄漏的。
也就是说,最好不要用退出线程函数来退出线程,用return自然返回是最好的。
内存释放:
- 内存释放这里也有个共同点; 创建线程后直接
CloseHandle
是可以的,这样的线程对象,在函数运行完了就自动释放(就算是_beginthread等有自释放代码的类型也同样适用)
AfxBeginThread
会自动CloseHandle
;相应endthread
函数也有CloseHandle
代码_beginthread
会自动CloseHandle
;相应endthread
函数也有CloseHandle
代码_beginthreadex
必须手动CloseHandle
CreateThread
必须手动CloseHandle
比较:
AfxBeginThread
创建的线程比较庞大,一般的后台运行线程是没必要的CreateThread
创建的线程无法使用CRT函数_beginthread
创建的线程可以使用CRT函数,但引用官方的话来说:“使用 _beginthreadex 比 _beginthread 更为安全”;