Getting Std::Thread/Mutex to Work Under Win7 with Mingw and G++ 4.7.2

Getting std::thread/mutex to work under Win7 with mingw and g++ 4.7.2

These MinGW-w64 builds support C++11 threads,atomic operations etc.

  1. MinGW-builds are now integrated into the MinGW-w64 project
  2. MinGW-builds (project is old and will not be updated, see point above)
  3. MinGW-w64 rubenvb 64-bit and 32-bit builds

Note that MinGW-w64 is not 64-bit only, but does support it, unlike the old MinGW(.org) which is missing quite a lot of the new Vista+ APIs, and of course 64-bit support.

mingw-w64 threads: posix vs win32

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.

c++11 std::async doesn't work in mingw

Maybe it's easier for me to interpret because I wrote that code, but it's not so hard, just look at the first line of the error output:

swap.cpp:22:14: error: invalid use of incomplete type 'class std::future<std::basic_string<char> >'

That's telling you that std::future is an incomplete type, i.e. it is declared but not defined. The next line tells you exactly where it's declared (then all the other errors are caused by trying to use that incomplete type in different ways.)

If you look in GCC's <future> header you'll see that the types are declared near the top, but then the definitions are dependent on this preprocessor condition:

#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
&& (ATOMIC_INT_LOCK_FREE > 1)

If you compile some simple tests with those macros you'll find out that _GLIBCXX_HAS_GTHREADS is not defined, and that's because your gcc -v shows

Thread model: win32

No one has provided the necessary code to make the C++11 thread features work on Windows yet.

Making <future> work would be harder, but it's not actually that difficult to enable <thread> and <mutex> but no one has stepped up to do the work yet. Yesterday I posted some ideas for how to enable the C++11 thread features for the win32 thread model: http://gcc.gnu.org/ml/libstdc++/2012-05/msg00020.html

Qt: mingw compiled library does only work with both library.so and library.lib file present

That's weird, I think you should get a *.a and *.dll files when building a shared lib with MinGW on Windows, as said in the documentation:

In windows, MinGW will output .a and .dll, MSVC2010 will ouput .lib and .dll. In linux, MinGW will output .so, .so.1, .so.1.0 and .so.1.0.0 – .lib, .a and .so are import libraries.

You definitely shouldn't rename your file!

Be careful to:

  • not to include the "lib" prefix after "-l" in your project file.
  • put everything after after "-l" in lower case as you're on Windows
  • not adding any extension to your library name after "-l"
  • add and reference the .h file used in your library

A real example using QtWebsocket lib:

INCLUDEPATH += "$${PWD}/include/"

LIBS += -L"$${PWD}/libs/" -lqtwebsocket
...
HEADERS += ... \
$${PWD}/include/QWsSocket.h \
...

In my include/ folder, I have the following file:

  • QWsSocket.h (taken from original project - required)

In my libs/ folder, I have the following file:

  • libQtWebsocket.a
  • QtWebsocket.dll

Edit: I struggled with this too initially. Have you tried to build your lib as a static lib instead (CONFIG += staticlib in your library project)? This might help you getting you *.pro file right before switching to using the shared library.

Edit 2: Ok, the fact that you get a *.so file is still a bit odd. In this question
the user has the same issue as you and keep both files, which is just a workaround. According to a later answer it seems that you need to modify your makefile to generate a file with the proper extension. Maybe this will help: http://www.mingw.org/wiki/sampleDLL



Related Topics



Leave a reply



Submit