ChatGPT解决这个技术问题 Extra ChatGPT

mingw-w64 threads: posix vs win32

I'm installing mingw-w64 on Windows and there are two options: win32 threads and posix threads. I know what is the difference between win32 threads and pthreads but I don't understand what is the difference between these two options. I doubt that if I will choose posix threads it will prevent me from calling WinAPI functions like CreateThread.

It seems that this option specify which threading API will be used by some program or library, but by what? By GCC, libstdc++ or by something else?

I found this: Whats the difference between thread_posixs and thread_win32 in gcc port of windows?

In short, for this version of mingw, the threads-posix release will use the posix API and allow the use of std::thread, and the threads-win32 will use the win32 API, and disable the std::thread part of the standard.

Ok, if I will select win32 threads then std::thread will be unavailable but win32 threads will still be used. But used by what?

Used by applications created using this gcc.
@devnull, isn't this determined by API that I will use? If I will select pthreads version of MinGW, then what will prevent me from using WinAPI for threads?
gcc will prevent you, or rather: become unstable
I came across this Visual Studio Code article (code.visualstudio.com/docs/cpp/config-mingw) about configuring MinGW-w64 for Windows and they seem to have gone for the posix version (also x86_64 and seh).

r
rubenvb

GCC comes with a compiler runtime library (libgcc) which it uses for (among other things) providing a low-level OS abstraction for multithreading related functionality in the languages it supports. The most relevant example is libstdc++'s C++11 <thread>, <mutex>, and <future>, which do not have a complete implementation when GCC is built with its internal Win32 threading model. MinGW-w64 provides a winpthreads (a pthreads implementation on top of the Win32 multithreading API) which GCC can then link in to enable all the fancy features.

I must stress this option does not forbid you to write any code you want (it has absolutely NO influence on what API you can call in your code). It only reflects what GCC's runtime libraries (libgcc/libstdc++/...) use for their functionality. The caveat quoted by @James has nothing to do with GCC's internal threading model, but rather with Microsoft's CRT implementation.

To summarize:

posix: enable C++11/C11 multithreading features. Makes libgcc depend on libwinpthreads, so that even if you don't directly call pthreads API, you'll be distributing the winpthreads DLL. There's nothing wrong with distributing one more DLL with your application.

win32: No C++11 multithreading features.

Neither have influence on any user code calling Win32 APIs or pthreads APIs. You can always use both.


You can always link gcc runtime and winpthreads statically, removing necessity of DLL inclusion.
It took me a while to find the corresponding option on Linux, so in case it helps someone else: The package g++-mingw-w64-x86-64 provides two files x86_64-w64-mingw32-g++-win32 and x86_64-w64-mingw32-g++-posix, and x86_64-w64-mingw32-g++ is aliased to one of them; see update-alternatives --display x86_64-w64-mingw32-g++.
Hmm, you say "...which do not have a complete implementation when GCC is built with its internal Win32 threading model.... MinGW-w64 provides a winpthreads (a pthreads implementation on top of the Win32 multithreading API) which GCC can then link in to enable all the fancy features." So if i select the win32 model, GCC can still enable all the features, because it makes use of winpthreads? But in the bullet below, you write "win32: No C++11 multithreading features". I don't understand. Does "which GCC can then link in to..." mean that if I don't select win32, it can then select... ?
@JohannesSchaub-litb Well, no. GCC's configury magic couples the internal thread model selection to libstdc++'s enabled features due to the latter being built on top of GCC's internal "gthread" wrapper (which is just a thin posix-like thread abstraction. Fundamental pieces for C++11 features are missing in that layer when you use --threads=win32. So as long as the missing bits aren't implemented in GCC, you must configure GCC with --threads=win32.
Can I use qt's mingw precompiled libraries, which use -win32, with other libraries that use -posix, and use both libraries in the same program?
M
Marc.2377

Parts of the GCC runtime (the exception handling, in particular) are dependent on the threading model being used. So, if you're using the version of the runtime that was built with POSIX threads, but decide to create threads in your own code with the Win32 APIs, you're likely to have problems at some point.

Even if you're using the Win32 threading version of the runtime you probably shouldn't be calling the Win32 APIs directly. Quoting from the MinGW FAQ:

As MinGW uses the standard Microsoft C runtime library which comes with Windows, you should be careful and use the correct function to generate a new thread. In particular, the CreateThread function will not setup the stack correctly for the C runtime library. You should use _beginthreadex instead, which is (almost) completely compatible with CreateThread.


In this case, what about the 3rd party threading libraries like boost or Qt? Is there any way yo use these libraries with mingw64 without having to figure out the underlying threading library for these? What would happen if I arbitrarily decide to use boost::threads with posix variant of mingw?
@user460153 some info qt-project.org/wiki/…
This answer is wrong. The GCC runtime has absolutely no influence on the Win32 APIs, at all.
T
Tom 7

Note that it is now possible to use some of C++11 std::thread in the win32 threading mode. These header-only adapters worked out of the box for me: https://github.com/meganz/mingw-std-threads

From the revision history it looks like there is some recent attempt to make this a part of the mingw64 runtime.


M
Melroy van den Berg

@rubenvb answer is fully correct, use the mingw posix compiler if you want to use std::thread, std::mutex, etc. For everybody who is using CMake, here is an example:

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}
)

Ideal for cross-compiling Linux apps to Windows.

Hint: For people who are using GTK3 and want to cross-compile their GTK application to Windows. You maybe want to download the Mingw Windows GTK bundle, downloaded and packaged from msys2.org so you don't need to: https://gitlab.melroy.org/melroy/gtk-3-bundle-for-windows