首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows线程:_beginthread vs _beginthreadex vs CreateThread C++

Windows线程:_beginthread vs _beginthreadex vs CreateThread C++
EN

Stack Overflow用户
提问于 2008-12-01 17:20:57
回答 17查看 99.4K关注 0票数 135

启动线程的更好方法是_beginthread_beginthreadx还是CreateThread

我正在尝试确定_beginthread_beginthreadexCreateThread的优缺点。所有这些函数都会将线程句柄返回给新创建的线程,我已经知道当出现错误时,CreateThread会提供一些额外的信息(可以通过调用GetLastError进行检查)……但是当我使用这些函数时,我应该考虑哪些事情呢?

我正在使用一个windows应用程序,所以跨平台兼容性已经是不可能的了。

我已经看过了msdn文档,我只是不能理解,例如,为什么有人会决定使用_beginthread而不是CreateThread,反之亦然。

干杯!

更新:好的,谢谢你的所有信息,我也读到了一些地方,如果我使用_beginthread()就不能调用WaitForSingleObject(),但是如果我在线程中调用_endthread(),那就不能工作了吗?这是怎么回事?

EN

回答 17

Stack Overflow用户

回答已采纳

发布于 2008-12-01 17:29:58

CreateThread()是一个原始的Win32应用程序接口调用,用于在内核级别创建另一个控制线程。

_beginthread()_beginthreadex()是在幕后调用CreateThread()的C运行时库调用。一旦CreateThread()返回,_beginthread/ex()负责额外的记账,以使C运行时库可用,并在新线程中保持一致。

在C++中,您几乎肯定应该使用_beginthreadex(),除非您根本不需要链接到C运行时库(也称为MSVCRT*.dll/.lib)。

票数 99
EN

Stack Overflow用户

发布于 2008-12-01 18:35:57

_beginthread()_beginthreadex()之间有几个区别。_beginthreadex()的行为更像CreateThread() (在两个参数和它的行为方式上)。

正如Drew Hall提到的,如果您使用的是C/C++运行时,则必须使用_beginthread()/_beginthreadex()而不是CreateThread(),以便运行时有机会执行它自己的线程初始化(设置线程本地存储等)。

在实践中,这意味着您的代码几乎不应该直接使用CreateThread()

_beginthread()/_beginthreadex()的MSDN文档中有很多关于这些差异的细节--更重要的是,由于_beginthread()创建的线程的线程句柄在线程退出时由CRT自动关闭,“如果_beginthread生成的线程快速退出,返回给_beginthread调用者的句柄可能无效,或者更糟糕的是,指向另一个线程”。

下面是CRT源代码中对_beginthreadex()的评论:

代码语言:javascript
复制
Differences between _beginthread/_endthread and the "ex" versions:

1)  _beginthreadex takes the 3 extra parameters to CreateThread
  which are lacking in _beginthread():
    A) security descriptor for the new thread
    B) initial thread state (running/asleep)
    C) pointer to return ID of newly created thread

2)  The routine passed to _beginthread() must be __cdecl and has
  no return code, but the routine passed to _beginthreadex()
  must be __stdcall and returns a thread exit code.  _endthread
  likewise takes no parameter and calls ExitThread() with a
  parameter of zero, but _endthreadex() takes a parameter as
  thread exit code.

3)  _endthread implicitly closes the handle to the thread, but
  _endthreadex does not!

4)  _beginthread returns -1 for failure, _beginthreadex returns
  0 for failure (just like CreateThread).

更新2013年1月:

VS2012的CRT有一个在_beginthreadex()中执行的额外初始化:如果进程是一个“打包的应用程序”(如果从GetCurrentPackageId()返回一些有用的东西),运行时将在新创建的线程上初始化MTA。

票数 39
EN

Stack Overflow用户

发布于 2012-10-19 08:01:15

通常,正确的做法是调用_beginthread()/_endthread() (或ex()变体)。但是,如果您将CRT用作.dll,则CRT状态将被正确初始化和销毁,因为CRT的DllMain将在分别调用CreateThread()ExitThread()或返回时使用DLL_THREAD_ATTACHDLL_THREAD_DETACH调用。

CRT的DllMain代码可以在VC\crt\src\crtlib.c下的VS安装目录中找到。

票数 25
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/331536

复制
相关文章

相似问题

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