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 构建中的 std::thread 不是根据线程句柄实现的。 编辑: 它是,但间接地,请参阅 rubenvb 的答案如何从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 的某个地方有一些 dloads,为什么不这样做呢? 嗨鲁本,很高兴有人对它感兴趣。目前无法在运行时进行选择,因为 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)

c++编译thread程序时加了<thread>但他就是给我报错说没加,我装了个mingw-w64也不行,咋回事?