将_beginthread返回的uintptr_t转换为HANDLE是否安全?

时间:2013-10-17 22:10:15

标签: c++ multithreading winapi visual-c++

1)这篇文章WaitForSingleObject : how to get handle from _beginthreadex的答案说,将uintptr_t返回_beginthreadex转换为HANDLE类型是合法的,那么将uintptr_t返回_beginthread转换为HANDLE类型是不安全的?

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

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

2 个答案:

答案 0 :(得分:2)

如果要使用Windows同步API,则需要控制HANDLE。使用从uintptr_t返回的_beginthread无法安全地转换为HANDLE值,以便与同步API一起使用。 _beginthread, _beginthradex的文档在这里非常清楚(强调我的):

  

你也可以使用_beginthreadex返回的线程句柄和同步API ,你不能用_beginthread

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

答案 1 :(得分:0)

我认为你所关联的问题的答案是误导性的,或者至少是不完整的。根据{{​​1}}和beginthread()的文档:

  

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

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

在x64版本中,DuplicateHandle()被定义为64位值:

uintptr_t

在这种情况下将其转换为typedef unsigned __int64 uintptr_t; 是安全的,而且确实是你想要做的。

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