【问题标题】:Where do I use _endthreadex - windows API我在哪里使用 _endthreadex - Windows API
【发布时间】:2012-12-27 08:25:03
【问题描述】:

我是 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 之前有它,这对我来说似乎很奇怪?我在有关_endthreadex 的 msdn 页面中读到,它在函数结束时自动调用,但您应该调用它以更好地清理内存,这就是我尝试将其放入的原因。它似乎不正确,抱歉,如果这是一个不好的问题。我只是想确保我尽我所能做好每一件事

【问题讨论】:

  • 使用 CreateThread 没有错。除非你还在使用古老的 MSVC。
  • @DavidHeffernan 如果您不使用 _begin/_endthread,静态链接 CRT 会出现内存泄漏问题。对此更改有参考吗?

标签: c++ c windows multithreading


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      _endthreadex(MyThreadFunction(...));
      

      也就是说,一旦您返回,_endthreadex 将立即为您调用并退出线程。

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

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

      MSDN 在Remarks section 中基本上解释了完全相同的内容。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-27
        • 1970-01-01
        相关资源
        最近更新 更多