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?
答案 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()
你负责关闭,这意味着可以安全地等待它。它是一个更有用,多功能的功能,但如果您不需要这些附加功能,则没有理由只为此而切换。