10

我是 Windows API 的新手,最近我了解到我不应该使用 CreateThread 和 TerminateThread。我切换到了_beginthreadex,但是我不确定我应该怎么做use _endthreadex

例如,这是我正在测试的一个基本功能:

// MyThreadFunction - outputs "#.) I Work" and ends
unsigned int __stdcall MyThreadFunction( void * lpParam ) 
{
    int i = (int)lpParam;
    cout << i << ".) I work! " << endl;
    _endthreadex(0);
    return 0;
}

我的位置_endthreadex正确吗?我在返回 0 之前有它,这对我来说似乎很奇怪?我在 msdn 页面中读到_endthreadex它会在函数结束时自动调用,但你应该调用它以更好地清理内存,这就是我尝试将它放入的原因。它看起来不对,如果这是一个抱歉不好的问题。我只是想确保我尽我所能做每一件事

4

3 回答 3

9

你实际上根本不需要打电话_endthreadex()。无论如何,在您的线程函数返回后,它将自动为您调用。

于 2013-01-13T03:48:24.323 回答
4

答案已经在简短版本中给出,如果您想了解更多 - 您的函数的返回实际上将用作_endthreadex调用中的参数。这是启动线程时运行时正在执行的操作。该线程确实从 CRT 中的某个起点开始,内部_callthreadstartex正在执行:

_endthreadex(MyThreadFunction(...));

也就是说,一旦你返回,_endthreadex就会立即为你调用,并且它会从线程中退出。

你能明确地使用它吗?是的,您可以,而且您的代码也很好,因为无论您自己调用它还是为您调用它都无关紧要,前提是在途中没有发生泄漏(例如,特别是尚未调用的析构函数)局部变量)。

由于无论如何都会为您调用它,并且从函数返回在释放本地资源方面更安全,因此进行显式调用没有任何用处、优势和意义。

MSDN 在备注部分基本上解释了完全相同的权利。

您可以显式调用 _endthread 或 _endthreadex 来终止线程;但是,当线程从作为参数传递给 _beginthread 或 _beginthreadex 的例程返回时,会自动调用 _endthread 或 _endthreadex。通过调用 endthread 或 _endthreadex 来终止线程有助于确保正确恢复为线程分配的资源。

于 2013-01-13T13:21:09.087 回答
2

如前所述,您不必调用它。关于您的代码,我认为 finalreturn 0;甚至不会被调用,因为_endthreadex()永远不会返回。这也可能导致不调用本地对象的析构函数(这是我相信 MSDN 想说的),因此在 C++ 中使用此函数甚至可能是有害的。考虑使用 Boost.Thread,他们有一个专门用于结束线程的异常,如果你想在中间的某个地方终止线程,它应该做正确的事情。

于 2013-01-13T11:09:03.113 回答