我在 Windows 上安装 mingw-w64,有两个选项:win32 线程和 posix 线程。我知道win32线程和pthreads有什么区别,但我不明白这两个选项有什么区别。我怀疑如果我选择 posix 线程,它会阻止我调用像 CreateThread 这样的 WinAPI 函数。
似乎这个选项指定了某个程序或库将使用哪个线程 API,但是用什么?通过 GCC、libstdc++ 还是其他方式?
我发现了这个:Whats the difference between thread_posixs and thread_win32 in gcc port of windows?
简而言之,对于这个版本的mingw,threads-posix版本会使用posix API并允许使用std::thread,threads-win32会使用win32 API,并禁用std::thread部分标准。
好的,如果我将选择 win32 线程,则 std::thread 将不可用,但仍将使用 win32 线程。但是被什么用?
GCC 带有一个编译器运行时库 (libgcc),它用于(除其他外)为它支持的语言中的多线程相关功能提供低级操作系统抽象。最相关的示例是 libstdc++ 的 C++11 <thread>
、<mutex>
和 <future>
,当 GCC 使用其内部 Win32 线程模型构建时,它们没有完整的实现。 MinGW-w64 提供了一个 winpthreads(在 Win32 多线程 API 之上的一个 pthreads 实现),然后 GCC 可以链接到它以启用所有花哨的功能。
我必须强调这个选项不会禁止您编写任何您想要的代码(它绝对不会影响您可以在代码中调用的 API)。它仅反映 GCC 的运行时库 (libgcc/libstdc++/...) 用于其功能的内容。 @James 引用的警告与 GCC 的内部线程模型无关,而是与 Microsoft 的 CRT 实现有关。
总结一下:
posix:启用 C++11/C11 多线程功能。使 libgcc 依赖于 libwinpthreads,因此即使您不直接调用 pthreads API,您也将分发 winpthreads DLL。在您的应用程序中再分配一个 DLL 并没有错。
win32:没有 C++11 多线程特性。
两者都不会影响任何调用 Win32 API 或 pthreads API 的用户代码。您始终可以同时使用两者。
GCC 运行时的某些部分(特别是异常处理)取决于所使用的线程模型。因此,如果您使用的是使用 POSIX 线程构建的运行时版本,但决定使用 Win32 API 在您自己的代码中创建线程,那么您可能会在某些时候遇到问题。
即使您使用的是运行时的 Win32 线程版本,您也可能不应该直接调用 Win32 API。引用 MinGW FAQ:
由于 MinGW 使用 Windows 附带的标准 Microsoft C 运行时库,因此您应该小心并使用正确的函数来生成新线程。特别是,CreateThread 函数不会为 C 运行时库正确设置堆栈。您应该改用 _beginthreadex,它(几乎)与 CreateThread 完全兼容。
请注意,现在可以在 win32 线程模式下使用一些 C++11 std::thread。这些仅包含标头的适配器对我来说是开箱即用的:https://github.com/meganz/mingw-std-threads
从修订历史来看,最近有人尝试将其作为 mingw64 运行时的一部分。
@rubenvb 答案完全正确,如果您想使用 std::thread
、std::mutex
等,请使用 mingw posix 编译器。对于使用 CMake 的每个人,这里有一个示例:
set(CMAKE_CXX_STANDARD 17) # or 20 if you want..
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc-posix)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++-posix)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
set(CMAKE_FIND_ROOT_PATH
/usr/${TOOLCHAIN_PREFIX}
)
非常适合将 Linux 应用程序交叉编译到 Windows。
提示: 适用于使用 GTK3 并希望将其 GTK 应用程序交叉编译到 Windows 的用户。您可能想要下载 Mingw Windows GTK 包,从 msys2.org 下载并打包,因此您不需要:https://gitlab.melroy.org/melroy/gtk-3-bundle-for-windows
g++-mingw-w64-x86-64
提供了两个文件x86_64-w64-mingw32-g++-win32
和x86_64-w64-mingw32-g++-posix
,x86_64-w64-mingw32-g++
是其中一个的别名;见update-alternatives --display x86_64-w64-mingw32-g++
。--threads=win32
时,在该层中。因此,只要缺少的位未在 GCC 中实现,您就必须使用--threads=win32
配置 GCC。