2

1)这篇帖子WaitForSingleObject的答案:如何从_beginthreadex获取句柄说将uintptr_t返回的_beginthreadex转换为类型HANDLE是唯一合法的,那么将uintptr_t返回的_beginthread转换为类型HANDLE是不安全的吗?

2)我们在 32 位应用程序中进行了如下转换,它似乎运行良好,当我将此应用程序转换为 64 位时会遇到任何问题吗?HANDLE 线程 = (HANDLE)_beginthread(checkThread, 0, &thrVal);

3) 是否值得将所有 _beginthread 调用转换为 _beginthreadex?

4

2 回答 2

2

如果要使用 Windows 同步 API,则需要HANDLE您自己控制。使用uintptr_t返回的 from_beginthread不能安全地转换HANDLE为用于同步 API 的值。_beginthread, _beginthradex的文档在这里很清楚(强调我的):

您还可以将 _beginthreadex 返回的线程句柄与同步 API 一起使用,而 _beginthread 则无法做到这一点

如果您不想依赖未记录的行为,则必须_beginthreadex在需要HANDLE与同步 API 一起使用的值时使用。

于 2013-10-17T22:18:50.733 回答
0

我认为您链接的问题的答案具有误导性,或者至少不完整。根据beginthread()and的文档beginthreadex()

如果成功,这些函数中的每一个都会返回一个新创建线程的句柄

两者的区别在于线程beginthread()在退出时是通过关闭自己的句柄来启动的。所以等待返回的句柄是不安全的,beginthread()因为在你等待它的时候它可能已经关闭或回收了。但是,如果您可以控制您启动的线程(通过使用其他形式的同步),您可以调用DuplicateHandle()以获得可以安全等待的句柄。

在 x64 构建中,uintptr_t定义为 64 位值:

typedef unsigned __int64    uintptr_t;

因此,HANDLE在这种情况下将其转换为 a 是安全的,并且确实是您应该做的。

_beginthreadex()让您可以更好地控制新线程,包括在挂起状态下启动它以及检索线程 ID。它还返回一个HANDLE负责关闭的,这意味着等待它是安全的。这是一个更有用、更通用的功能,但如果您不需要这些附加功能,则没有理由仅仅为了它而切换。

于 2013-10-17T22:13:02.057 回答