使用Windows API的mingw std::thread

3
我开始使用C++11的std::thread(mingw 4.8),目前还不错。我遇到了一个关于重叠I/O的情况,其中sleepEx用于将线程置于可警报等待状态。这很有效,但当需要使用QueueUserAPC时,它返回“无效句柄错误”。
经过一些搜索,发现std::thread在Windows下使用pthread库。
有没有办法使用期望线程句柄的Windows API调用来配合std::thread使用? 还是说我需要坚持使用Windows线程来处理重叠I/O?

我不熟悉Windows API,但听起来你正在将Windows API线程与C++11 std::threads混合使用,而由于mingw 4.8在底层使用pthreads,这会导致问题。这是正确的吗?即使有一种方法可以让mingw std::threads使用Windows API线程而不是pthreads,最好还是只使用一个线程API。 - Nicu Stiurca
3个回答

5
为了解决您的问题,MinGW-w64 winpthreads(您正在使用的pthread实现)与pthreads-win32一样,允许您获取pthread的本机Win32线程句柄。
void * pthread_gethandle (pthread_t t);

请注意,这是目前未记录的函数。
在pthreads-win32中对应的函数是:
HANDLE pthread_getw32threadhandle_np(pthread_t thread);

我敢打赌这会让你混合使用两者变得更加顺畅,或者至少能够揭示一些winpthreads中的错误,这些错误可以被修复。如果是后一种情况,请将它们报告给MinGW-w64。
如果上述操作返回无效句柄,最好的办法是在MinGW-w64公共邮件列表上询问(先订阅,否则你将不得不等待手动审核,这很愚蠢)。

不错,将该函数与 std::thread::native_handle() 结合使用可能会起作用。 - Jonathan Wakely
很不幸,GCC4.8附带的pthread.h没有包含pthread_getw32threadhandle_np。 - Waldorf
@Waldorf好的。看起来我在winpthreads源代码树中找到了一个pthread-win32测试文件并正在使用它。那么pthread_gethandle呢,它似乎会返回一个HANDLE。请注意,此函数是一个实现细节。 - rubenvb
谢谢!虽然它似乎是一个未记录的函数,但它按预期工作。当传递native_handle时,它返回一个有效的Windows线程句柄,并且一切都按预期工作。 - Waldorf

3
有没有办法使用期望线程句柄的Windows API调用 std::thread?不,因为MinGW构建中的std::thread并非基于线程句柄实现。但是,可以间接地使用pthread_t获取本机线程句柄,然后可以使用std::thread::native_handle()获取pthread_t。GCC尚未实现必要的支持,使C++11线程库能够直接使用本机Windows线程。我有一些新线程模型的想法,该模型将基于本机互斥和条件变量实现。这将允许您调用std::thread::native_handle()以获取底层线程句柄,以便与Windows API一起使用。

我已经将我的更改应用到重新构建的GCC中,但无法测试它们。几乎没有人对我的建议感兴趣,也没有任何MinGW贡献者提供帮助,所以由于我不是Windows用户,并且在Windows上工作和构建MinGW非常痛苦和沮丧,我放弃了。我应该在某个地方在线上发布我的更改,以便有比我更有耐心的人可以在未来完成这项工作。


2
我关注了你与活跃在MinGW-w64邮件列表上的K. Frank的讨论。他实现了仅适用于Vista+的gthread包装器代码,使std::thread可用于Win32本地原语。正如你所说,这是不可接受的,没有新的线程模型来允许XP兼容的工具链。我知道这不是讨论这个问题的好地方,但是否可以在两种实现之间进行运行时选择(一种慢的XP,另一种快的新版本)?我相信在GCC中有一些dload,为什么不用在这里呢? - rubenvb
2
嗨,Ruben,很高兴听到有人对此感兴趣。目前无法在运行时进行选择,因为gthread包装器是内联函数或编译到libgcc中的,使用的代码是在配置GCC时选择的。理论上,我想一个新的Vista+ gthread模型可以让libgcc调用其他DLL,并且该DLL可以有另外的实现。这将需要相当多的更改,但我愿意帮助将其纳入GCC中(可能要等到明年2月/ 3月之后)。 - Jonathan Wakely

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接