【问题标题】:Trouble understanding MSDN's documentation on _beginthreadex and _endthreadex无法理解 MSDN 关于 _beginthreadex 和 _endthreadex 的文档
【发布时间】:2010-10-16 22:12:12
【问题描述】:

我正在阅读关于_beginthreadex_endthreadexdocumentation,但有些事情我不明白。

请注意,文档会同时记录“扩展”和正常功能,但我没有使用_beginthread_endthread;只有他们的扩展版本。


您可以调用 _endthread 或 _endthreadex 显式终止线程;但是,_endthread 或 _endthreadex 在线程从 例程作为参数传递。 通过调用来终止线程 endthread 或 _endthreadex 有助于 确保适当回收资源 分配给线程。

  • 如果_endthreadex是自动调用的,那么调用它如何有助于确保“正确回收资源”?不管我叫还是不叫都应该没什么区别?

_endthread 自动关闭线程句柄(而 _endthreadex 才不是)。因此,当使用 _beginthread 和 _endthread,不要显式关闭线程句柄 调用 Win32 CloseHandle API。

  • 如果_endthreadex关闭手柄,为什么我不应该用CloseHandle关闭它?
  • 我所有的线程只是通过从它们的主函数返回来自愿终止,并且永远不会被强制终止。根据文档,当这种情况发生时,_endthreadex 会被自动调用。

    这虽然不会关闭句柄。假设我确实需要关闭它,尽管上面说了些什么,我该怎么做,因为此时线程已经死了?我应该以某种方式从另一个线程关闭它吗?如果我让它打开会怎样?

【问题讨论】:

标签: c++ multithreading winapi


【解决方案1】:

如果 _endthreadex 被自动调用,为什么调用它有助于确保“正确回收资源”?不管我叫还是不叫都应该没什么区别吧?

我认为他们的意思是在您不使用标准方式终止线程的情况下。

如果 _endthreadex 没有关闭 处理,我怎么不应该关闭它 使用 CloseHandle?

使用_endthreadex 时,应使用CloseHandle 将其关闭。文档说只有_endthread 关闭句柄(因此CloseHandle 调用是多余的)。

我所有的主题都是自愿的 通过从他们的主要返回终止 功能,从不强制 终止。根据 文档,当这种情况发生时 _endthreadex 被自动调用。

从启动它的线程中关闭线程句柄是一种常用的解决方案。您应该记住句柄并在适当的位置等待线程完成(使用WaitForSingleObject)然后关闭其句柄。如果你不这样做,你将导致资源泄漏。如果你有几个线程,这通常不是什么大问题,但绝对不是一个好习惯。

【讨论】:

  • 如果我在线程的主函数中关闭句柄会发生什么?
  • 我猜这是一个未定义的行为。它可能会工作,它可能会泄漏,它可能会死锁,它可能会崩溃。最糟糕的是 - 它可以随时更改并且在不同的计算机之间有所不同。
  • @KarelPetranek 你能解释一下为什么从线程内调用CloseHandle 会是未定义的行为吗?你能提供一个参考吗? CloseHandle 的 MSDN 文档声明它不会终止线程,所以我看不出它应该是线程内的 UB 的任何明显原因。
  • @jamesdlin The documentation for the functions that create these objects indicates that CloseHandle should be used when you are finished with the object, and what happens to pending operations on the object after the handle is closed. In general, CloseHandle invalidates the specified object handle, decrements the object's handle count, and performs object retention checks. After the last handle to an object is closed, the object is removed from the system.To remove a thread object, you must terminate the thread, *then* close all handles to the thread
  • @KarelPetranek 对我来说,这似乎类似于典型的 CreateProcess 用法,如果调用者不关心返回的进程和线程句柄,它会立即关闭它们。并且鉴于CloseHandle 不会删除线程对象,那么即使在正在运行的线程的句柄上调用了线程本身,它也应该仍然有效,而不管CloseHandle 是从哪个线程调用的。所以在我的解释中,行为不应该是不确定的,最坏的情况可能是资源泄漏(但我也不认为这是真的)。​​
【解决方案2】:

不要调用_endthread_endthreadex,除非你想快速异常终止线程。虽然 CRT 将释放它自己的每个线程数据,但不会调用任何线程对象的 C++ 析构函数。它的行为类似于 _exit 在不调用析构函数的情况下结束进程的方式。

结束线程的正常方法应该是从作为参数传递给_beginthread_beginthreadex 的函数返回。这将导致 C++ 析构函数作为函数返回的正常部分被调用。

参考:https://stackoverflow.com/a/31257350/6364089

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 2010-09-27
    • 1970-01-01
    相关资源
    最近更新 更多