mingw std::thread 与 Windows API
Posted
技术标签:
【中文标题】mingw std::thread 与 Windows API【英文标题】:mingw std::thread with Windows API 【发布时间】:2013-10-08 14:08:21 【问题描述】:到目前为止,我开始使用 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,因此这是领先的到问题。它是否正确?最好只使用一个线程 API,即使有办法让 mingw std::threads 使用 Windows API 线程而不是 pthreads。 【参考方案1】:为了解决您的问题,MinGW-w64 winpthreads(您正在使用的 pthreads 实现),就像 pthreads-win32 一样,允许您获取 pthread 的本机 Win32 线程句柄:
void * pthread_gethandle (pthread_t t);
请注意,这是当前未记录的函数。
pthreads-win32中对应的函数是:
HANDLE pthread_getw32threadhandle_np(pthread_t thread);
我敢打赌,这将使您将两者混合使用,或者至少揭示一些可以修复的 winpthreads 中的错误。在后一种情况下,请向 MinGW-w64 报告。
如果上面返回一个无效的句柄,最好的办法是在 MinGW-w64-public 邮件列表上询问(先订阅,否则你将不得不等待手动审核,这很愚蠢)。
【讨论】:
很好,将该功能与std::thread::native_handle()
结合起来可能会起作用。
不幸的是,GCC4.8 附带的 pthread.h 不包括 pthread_getw32threadhandle_np。
@Waldorf 好的。似乎我在使用它的 winpthreads 源代码树中找到了一个 pthreads-win32 测试文件。 pthread_gethandle 似乎是return a HANDLE
怎么样。请注意,此函数是一个实现细节。
谢谢!尽管它似乎是一个未记录的功能,但它可以按预期工作。当传递 native_handle 时,它会返回一个有效的 Windows 线程句柄,并且一切都按预期工作。【参考方案2】:
有什么方法可以使用需要 std::thread 线程句柄的 Windows API 调用?
不,因为您的 MinGW 构建中的 编辑: 它是,但间接地,请参阅 rubenvb 的答案如何从std::thread
不是根据线程句柄实现的。pthread_t
获取本机线程句柄,您应该可以使用std::thread::native_handle()
获取pthread_t
。
没有人在 GCC 中实现了对 C++11 线程库的必要支持,以直接使用本机 Windows 线程。
我有一些ideas 用于新的thead 模型,该模型将根据本机互斥锁和条件变量来实现。这将允许您调用 std::thread::native_handle()
以获取底层线程句柄以与 Windows API 一起使用。
我已经应用了我的更改来重建 GCC,但无法对其进行测试。我的建议几乎没有兴趣,也没有任何 MinGW 贡献者提供帮助,所以我不是 Windows 用户,在 Windows 上工作和构建 MinGW 是如此痛苦和令人沮丧,我放弃了。我应该把我的更改放到网上某个地方,这样比我更有耐心的人总有一天能完成这项工作。
【讨论】:
我关注了您与活跃在 MinGW-w64 邮件列表中的 K. Frank 的讨论。他实现了仅 Vista+ 的 gthread 包装器代码,使 std::thread 在 Win32 本机原语上可用。正如您所说,如果没有新的线程模型以允许与 XP 兼容的工具链,这是不可接受的。我知道这是一个不好的地方进行讨论,但是可以在两种实现之间进行运行时选择吗(一种对于 XP 来说很慢,对于较新的版本来说另一种快)?我确定在 GCC 的某个地方有一些dload
s,为什么不这样做呢?
嗨鲁本,很高兴有人对它感兴趣。目前无法在运行时进行选择,因为 gthread 包装器是内联函数或编译到 libgcc 中,并且在配置 GCC 时选择使用的代码。理论上,我认为新的 Vista+ gthread 模型可以将 libgcc 调用到其他一些 DLL 中,并且可能有该 DLL 的替代实现。这将需要进行大量更改,但我愿意帮助将其纳入 GCC(可能不会在明年 2 月/3 月之前)【参考方案3】:
已经有 std::thread 和同步原语的本机 win32 实现,请参阅:
https://github.com/meganz/mingw-std-threads
这是一个只有头文件的库,适用于任何对 C++11 具有适当语言支持的 MinGW 版本
【讨论】:
以上是关于mingw std::thread 与 Windows API的主要内容,如果未能解决你的问题,请参考以下文章
std::thread 不是使用 Eclipse Kepler MinGW 命名空间 std 的成员
mingw-w64 gcc std::thread 行为异常
为啥 MinGW 中仍然没有 std::thread、std::promise 和 std::future? win32中promise和futures的替代方案是啥?
在带有标志选项 -m32 的 gcc-8.2.2 上找不到 std::thread。我正在使用 mingw
mingw-w64线程模型:posix vs win32(posix允许使用c++11的std:: thread,但要带一个winpthreads,可能需要额外dll)