启动线程的更好方法是_beginthread、_beginthreadx还是CreateThread
我正在尝试确定_beginthread、_beginthreadex和CreateThread的优缺点。所有这些函数都会将线程句柄返回给新创建的线程,我已经知道当出现错误时,CreateThread会提供一些额外的信息(可以通过调用GetLastError进行检查)……但是当我使用这些函数时,我应该考虑哪些事情呢?
我正在使用一个windows应用程序,所以跨平台兼容性已经是不可能的了。
我已经看过了msdn文档,我只是不能理解,例如,为什么有人会决定使用_beginthread而不是CreateThread,反之亦然。
干杯!
更新:好的,谢谢你的所有信息,我也读到了一些地方,如果我使用_beginthread()就不能调用WaitForSingleObject(),但是如果我在线程中调用_endthread(),那就不能工作了吗?这是怎么回事?
发布于 2008-12-01 17:29:58
CreateThread()是一个原始的Win32应用程序接口调用,用于在内核级别创建另一个控制线程。
_beginthread()和_beginthreadex()是在幕后调用CreateThread()的C运行时库调用。一旦CreateThread()返回,_beginthread/ex()负责额外的记账,以使C运行时库可用,并在新线程中保持一致。
在C++中,您几乎肯定应该使用_beginthreadex(),除非您根本不需要链接到C运行时库(也称为MSVCRT*.dll/.lib)。
发布于 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()的评论:
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。
发布于 2012-10-19 08:01:15
通常,正确的做法是调用_beginthread()/_endthread() (或ex()变体)。但是,如果您将CRT用作.dll,则CRT状态将被正确初始化和销毁,因为CRT的DllMain将在分别调用CreateThread()和ExitThread()或返回时使用DLL_THREAD_ATTACH和DLL_THREAD_DETACH调用。
CRT的DllMain代码可以在VC\crt\src\crtlib.c下的VS安装目录中找到。
https://stackoverflow.com/questions/331536
复制相似问题