☆──────────────────────────────────────☆
yixin (@_@) 于 2009年09月18日11:00:47 星期五)
提到:
代码:
#include <string>
#include <process.h>
#include <windows.h>
#include <iostream>
using namespace std;
//#include <vld.h>
unsigned __stdcall th_ThreadA()
{
string a;
}
int main()
{
for ( int i = 0; i < 10; i ++)
))&th_ThreadA, NULL, 0,&idThread);
}
}
这里如果显式调用_endthreadex则string会泄露,如果直接return则不会
但是为什么网上的示例代码包括msdn都显示调用_endthreadex
并且说这样可以防止内存泄露?
☆──────────────────────────────────────☆
enjoysoft (EnjoySoft Inc.) 于 2009年09月18日15:35:55 星期五 提到:
好问题!
std::string的资源释放是由析构函数进行的,C++会保证
但是析构函数是在return 以后发生的
这个代码return语句永远不会被运行,因为endthreadex的存在,和exit是类似的
不写endthreadex你的线程也能正确退出
所以如果不是提前退出的话,你可以不写endthreadex,函数返回后系统会调用endthrea
dex的,参见《Windows核心编程》
如果你要提前退出的话,请使用大括号:
{
string a;
...
} // a released here
_endthreadex(0);
【 在 yixin (@_@) 的大作中提到: 】
: 代码:
: #include <string>
: #include <process.h>
: #include <windows.h>
: #include <iostream>
: using namespace std;
: //#include <vld.h>
: unsigned __stdcall th_ThreadA()
: {
: string a;
: .................(以下省略)
☆──────────────────────────────────────☆
yixin (@_@) 于 2009年09月18日16:51:03 星期五)
提到:
那既然任何需要退出的地方都能用return完成
是不是endthreadex就没有显式调用的意义了?
【 在 enjoysoft 的大作中提到: 】
: 好问题!
: std::string的资源释放是由析构函数进行的,C++会保证
: 但是析构函数是在return 以后发生的
: 这个代码return语句永远不会被运行,因为endthreadex的存在,和exit是类似的
: 不写endthreadex你的线程也能正确退出
: 所以如果不是提前退出的话,你可以不写endthreadex,函数返回后系统会调用endth..
: dex的,参见《Windows核心编程》
: 如果你要提前退出的话,请使用大括号:
: {
: string a;
: ...
: } // a released here
: _endthreadex(0);
: (以下引言省略...)
☆──────────────────────────────────────☆
dog (@_@) 于 2009年09月18日21:25:42 星期五 提到:
应该是的吧,看msdn上也没说有调用的必要,return的时候会自动调用_endthreadex如
果你是 _beginthreadex创建的话
调用_endthreadex是必须的,但不是指显示调用,这是我对msdn有关说明的理解。
所谓必须是清理_beginthreadex为thread创建的tiddata。
【 在 yixin (@_@) 的大作中提到: 】
: 那既然任何需要退出的地方都能用return完成
: 是不是endthreadex就没有显式调用的意义了?
: .................(以下省略)
☆──────────────────────────────────────☆
yixin (@_@) 于 2009年09月18日21:32:18 星期五 提到:
了解
thx
只是以前看示例代码都是显示调用的
【 在 dog (@_@) 的大作中提到: 】
: 应该是的吧,看msdn上也没说有调用的必要,return的时候会自动调用_endthreadex如
: 果你是 _beginthreadex创建的话
: 调用_endthreadex是必须的,但不是指显示调用,这是我对msdn有关说明的理解。
: 所谓必须是清理_beginthreadex为thread创建的tiddata。
☆──────────────────────────────────────☆
dog (@_@) 于 2009年09月18日21:34:42 星期五 提到:
好处没看到,
倒是看到板主说的那些了。。msdn上圈起来突出显示的。。
【 在 yixin (@_@) 的大作中提到: 】
: 了解
: thx
: 只是以前看示例代码都是显示调用的
☆──────────────────────────────────────☆
enjoysoft (EnjoySoft Inc.) 于 2009年09月18日22:56:46 星期五)
提到:
以讹传讹的故事太多了,_endthreadex就是一例。
要说_endthreadex完全没有用肯定是不对的,_endthreadex并不是一个过时的函数,正确
的使用并不会带来问题。
比如在线程的主函数中,return是_endthreadex的一个良好替代,就像main函数里面retu
rn是exit()或ExitProccess()的良好替代一样,但是这不表示exit函数没用。比如线程调
用了一个子函数,如果子函数决定退出线程,return是没用的,_endthreadex即可终结线
程。
但是这个设计不好,因为可能造成LZ提出的资源泄漏。尤其考虑到后台线程终结后的资源
泄漏比主线程的资源泄漏更要命(主线程退出后,进程就退出了,OS会清理一切资源,无
所谓泄露不泄露,而子线程退出后主线程可能还会运行很久,并且可能有大量的同类型的
子线程退出,会造成要命的泄露)
良好的设计还是返回线程的主函数,让threadproc来决定是不是要退出,从这个意义上说
,_endthreadex没有必要。
微软也指出,有些程序员就是要调用exit系列函数(ExitThread,ExitProccess等),没
辙,只好提供了。
转自:http://bbs.sjtu.edu.cn/bbscon,board,VC,file,M.1256696811.A.html