首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确使用_beginthread和端点

如何正确使用_beginthread和端点
EN

Stack Overflow用户
提问于 2015-07-06 10:59:09
回答 1查看 5K关注 0票数 4

我习惯于使用好的旧WinAPI调用CreateThread(),并使用等待函数(例如WaitForSingleObject() )检查线程的状态,一旦线程用WAIT_OBJECT_0发出信号,我就使用CloseHandle().关闭线程

最近,我决定转移到beginthread,并在某种程度上避免未初始化的crt和可能发生的意外内存泄漏的风险。

这样做让我很困惑。

  1. endthread()的确切用途是什么?为什么当我在主函数中调用CloseHandle()时,在线程执行之后,CloseHandle()会以无效的句柄崩溃?
  2. 我应该关闭beginthread返回的句柄吗?
  3. endthread,正如我所理解的,一旦函数超出作用域,线程就会自动调用它,所以应该在超出作用域之前调用它吗?
  4. 根据msdn,端点线程已经调用了CloseHandle() 1。线程从哪里获得对其句柄的引用/实例。2.如果我坚持使用endthread(),那么它应该是线程中的最后一个命令吗?

谢谢

编辑:描述 MSDN文件的泄漏,这里

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-06 23:26:31

正如David的评论中所述,您可以简单地将代码更改为使用CreateThread。当您第一次使用使用每个线程数据的函数时,Visual运行时将自动初始化C++的每个线程数据。

当线程结束时,CRT还会自动释放每个线程的数据,因此使用CreateThread不会导致内存泄漏。有一个例外,如果下列所有条件都为真,那么每个线程数据都不会自动释放:

  • 您正在构建可执行文件,而不是DLL
  • 您将链接到CRT库的静态版本(LIBCMT.LIB),而不是DLL版本(MSVCRT.LIB)。
  • 您构建的可执行文件在Windows (或早期版本的Windows)下运行。

请注意,即使在您的情况下所有这些都是正确的,内存泄漏也不会很严重,除非您正在创建一个长期存在的应用程序,该应用程序在其生命周期内创建并销毁了数十万个线程。

如果仍然希望使用CRTs线程创建函数(_beginthread/_beginthreadex),则应遵循以下指导原则:

  • 永远不要使用_beginthread返回的句柄。使用_beginthread时,线程句柄会在线程退出时自动关闭,这可能会在_beginthread返回之前发生。您不能在WaitForSingleObject中安全地使用它,因为在调用此函数之前,线程可能已经退出。如果您想要将线程句柄用于任何操作,请使用_beginthreadex
  • 永远不要关闭_beginthread返回的句柄。CRT将自动完成它,正如前面所描述的,在您有机会之前可能会这样做。
  • 当您不再需要句柄时,应该始终关闭_beginthreadex返回的句柄。CRT不会自动为你做这件事,所以这是你自己的责任。
  • 不要调用_endthread_endthreadex,除非您想要快速和异常地终止线程。尽管CRT将释放它自己的每个线程数据,但是不会调用任何线程对象的C++析构函数。它的行为类似于_exit如何在不调用析构函数的情况下结束进程。
  • 结束线程的正常方法应该是从作为参数传递给_beginthread_beginthreadex的函数返回。这将导致调用C++析构函数作为函数返回的正常部分。
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31244131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档