mingw-w64 threads: posix vs win32
Asked Answered
A

4

184

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?

Azal answered 21/6, 2013 at 19:1 Comment(4)
Used by applications created using this gcc.Cutback
@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?Azal
gcc will prevent you, or rather: become unstableArvie
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).Stepson
R
181

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.

Rakel answered 22/5, 2015 at 7:0 Comment(13)
You can always link gcc runtime and winpthreads statically, removing necessity of DLL inclusion.Expository
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++.Guggenheim
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... ?Snavely
@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.Rakel
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?Snavely
I found the github.com/meganz/mingw-std-threads library which can be installed if the win32 model is used. It provides the threading standard headerSnavely
@AlexanderShishenko Why linking statically would prevent DLL inclusion ?Armored
What if my code relies on GCC's Thread-Local-Storage extension keyword __thread? Is Win32 or Posix better on this ? or either is ok?Yokel
@Mr.WangfromNextDoor I think for TLS there's identical specific MinGW-w64 code handling that regardless of win32 or posix threading configured. But I'm not 100% sure.Rakel
Thank you. How we can learn about these details please in more depth? Can you recommend a book?Mozellemozes
No one wrote a book. I was just close to the people that set this up and provided a first (one of the first?) builds for other people with winpthreads linked into libstdc++.Rakel
You said neither options would have any influence on what API you could use, but also said if you chose win32, you couldn't use std::thread? I am confused.Insurgent
GCC libstdc++ implements std::thread on top of posix threads. It couples that choice to what it can provide in its libstdc++. Choosing posix threading for GCC doesn't preclude you from using the win32 API threads in your code. Choosing win32 threading for GCC does not prevent you from using pthreads through the separate winpthreads library. The only thing that depends on GCC's posix/win32 threading is what features the resulting libstdc++ has available.Rakel
O
21

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.

Oringa answered 22/6, 2013 at 19:13 Comment(4)
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?Flatfooted
@user460153 some info qt-project.org/wiki/…Windbound
This answer is wrong. The GCC runtime has absolutely no influence on the Win32 APIs, at all.Rakel
@Rakel This answer is correct in the sense of the rules for client programs, albeit somewhat misleading about the reasons. There are few public guarantees of interoperations in ISO C++, and there almost are no such ones complemented by MinGW runtimes to ensure that implementation-defined things will absolutely remain unchanged in future (actually some are in the libstdc++ docs which are out of the scope of MinGW). GCC also does not expose the deatils of thread model implementations as public API, so there are no mapping between them and the Win32 API can be assumed.Henchman
P
16

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.

Perlman answered 19/9, 2015 at 15:32 Comment(0)
T
1

@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

Torso answered 3/9, 2021 at 23:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.