[Mingw-w64-public] Thoughts on supporting the C++11 thread library on Windows
Wed May 9 13:29:00 GMT 2012
On 7 May 2012 18:28, K. Frank wrote:
> Hello Gabriel (and Ruben)!
> By the way, I'm the guy Ruben mentioned in his subsequent post.
> On Sat, May 5, 2012 at 11:20 PM, Gabriel Dos Reis
> <firstname.lastname@example.org> wrote:
>> Including the mingw64 project about this.
>> On Sat, May 5, 2012 at 5:59 PM, Jonathan Wakely <email@example.com> wrote:
>>> For GCC 4.7 I enabled most of <thread> (without timed mutexes) on Mac
>>> OS X by making the _GLIBCXX_HAS_GTHREADS macro more fine-grained. I
>>> think we could quite easily do the same again for the win32 thread
>>> model (defined in gthr-win32.h) so that <thread> and <mutex> are
>>> available (including timed mutexes), but without <condition_variable>
>>> and <future>.
> Just my opinion: One could make the macro more fine-grained, but I
> really wouldn't want to do this. If I'm using <thread> I'm using c++11,
> so I like to think I'm in the "modern world." I think (in the modern world)
> that condition variables are a core part of threading, so I'd find is a
> significant limitation if my c++11 implementation didn't have them.
Well currently you get none of the thread support when GCC is built
with --enable-threads=win32. IMHO that's an even more significant
limitation than no <condition_variable>
> (Also, I think that once you have the threading primitives (<thread>,
> <mutex>, and <condition_variable>), you get <future> "for free" in the
> sense that it's written on top of the primitives, and you don't need any
> further os-specific support.)
>>> It's harder to support <condition_variable> because Windows didn't
>>> provide condition variables until Vista, and even then they interact
>>> with a CRITICAL_SECTION and gthr-win32.h defines mutexes in terms of a
>>> semaphore not a critical section.
> Even leaving condition variables aside, I really don't think you want to
> implement mutexes in terms of windows semaphores (or windows mutexes)
> (unless your primary goal is to support older (pre-xp?) versions of windows.)
Too late. That's how they're implemented when GCC is built with
> I believe (speaking from memory) that I built a trial implementation of <thread>
> using windows mutexes and that it was much slower than using windows
> critical sections. I think both creation and locking were slower, but I don't
> remember the details. This is reasonable, because windows mutexes (and
> semaphores) are heavier-weight objects -- they provide cross-process
> synchronization, not just intra-process, cross-thread synchronization.
> And, as you mentioned, if you want to support condition variables (in terms
> of windows condition variables), you need to base your mutexes on windows
> critical sections.
>>> Douglas Schmidt describes an
>>> implementation of condition variables at
>>> http://www.cs.wustl.edu/~schmidt/win32-cv-1.html but that also
>>> requires mutexes to be critical sections - maybe that could be adapted
>>> to use the gthr-win32.h semaphore-based definition of
>>> __gthread_mutex_t, I haven't looked into it in detail. My suggestion
>>> would be to support <thread> and <mutex> but not <condition_variable>
>>> (or <future> because our implementation uses a
> My personal feeling is that a version of <thread> that is complete
> (i.e., supports condition variables and futures), but requires windows
> vista or later is a fine way to go.
> Certainly given an either-or choice of an incomplete <thread> that
> works pre-vista, or a complete <thread> that requires vista or later,
> I would certainly vote for the complete <thread> and forgo pre-vista
>>> I have some untested implementations of
>>> __gthread_create, __gthread_join etc. if anyone wants to work on
>>> implementing that suggestion. I don't have a Windows machine or
>>> enough free time to do that myself in the near future.
>>> As a second idea, supporting the full C++11 thread library could be
>>> done by creating a new thread model to be used instead of win32, which
>>> would only be supported on Vista or later and would use Windows
>>> critical sections for std::mutex and Windows condition variables for
> I've done this, and it seems to work fine. I would recommend it.
> (I'm not sure what you mean by "a new thread model to be used instead
> of win32."
I mean instead of GCC's win32 thread model that you get by building
That existing thread model uses semaphores.
My first suggestion is to improve that one in limited ways, retaining
backwards compatibility but adding <thread> and <mutex> which AFAIK
don't currently work.
My second suggestion is to write a replacement (call it
--enable-threads=win64 for the sake of argument) which would use
critical sections and support <thread>, <mutex>, <ondition_variable>
The suggestions are independent of each other.
> The way I look at it I used win32, i.e., I implemented <thread>
> on top of the vista-and-later version of win32.)
>>> Critical sections don't support a timed
>>> wait, so that thread model would be similar to the Mac OS X support
>>> and omit timed mutexes.
> I had to write some extra code to get timed mutexes to work. I used
> windows critical sections (just as for untimed mutexes), but spawned
> a helper thread that blocked on the critical section, and had the original
> thread use a timed windows WaitForSingleObject to wait (with a
> timeout) for the helper thread.
Spawning a new thread to block on a mutex seems over the top, but if
it works it works.
>>> That could easily be solved by implementing
>>> std::timed_mutex as a Windows mutex instead of a critical section,
> Again, I wouldn't recommend using windows mutexes as you would
> lose condition variables.
No you wouldn't. std::condition_variable only works with std::mutex
(which we agree should use a critical section), so it's irrelevant how
std::timed_mutex is implemented. If you want to use a condition
variable with a std:timed_mutex then you have to use
std::condition_variable_any and that internally uses a std::mutex, so
can internally use native OS condition varaibles.
> Also, as I mentioned above, they are much
> more expensive than critical sections.
>>> that would be difficult in the current Gthreads design because it
>>> follows POSIX and assumes that a timed mutex is exactly the same type
>>> as a non-timed mutex and you just use a different function to wait.
>>> We should consider adding a __gthread_timed_mutex type which can be
>>> different to __gthread_mutex_t, but would be the same type on POSIX
>>> platforms that support the Timeouts option and define
>>> pthread_mutex_timedlock. Again, I have some sketches to make that
>>> work but nothing concrete.
>>> If there are any Windows hackers out there who want to improve thread
>>> support on their platform please get in touch, I'll be happy to help
>>> and advise (although not for the next two weeks as I'm about to go on
> I have a pretty complete mingw / mingw-w64 <thread> implementation
> that uses win32 directly and doesn't rely on pthreads. I'd certainly be
> happy to make it available, if people would find it useful. As noted, it
> requires vista or later. (I've only tested in on 64-bit windows 7.)
> But I'm not sure that there is any problem that needs to be solved.
> For my own <thread> programming, I have been using "The Mighty
> Ruben's Wacky Build" (TM) of mingw-w64 gcc 4.7.0 that has <thread>
> implemented on top of winpthreads. It passes all of my (not particularly
> complete) <thread> tests. Presumably it works pre vista.
> And although I don't care much about pthreads, as a practical matter
> there is an awful lot of pthreads code out there so a mingw-w64
> offering that doesn't support pthreads would be a significant limitation.
> Now that mingw-w64 has winpthreads, it's very little work to modify
> the linux gcc <thread> implementation to work on windows.
There isn't a linux <thread> implementation, there is a POSIX one,
used by building GCC with --enable-threads=posix. I expect that
already works on Windows, I'm only talking about
> you get the added benefit that you can more easily mix pthreads
> code with c++11 <thread> code because they use the same
> underlying threading implementation (if you care).
> Also, there are (as would be expected) some performance differences.
> I ran some tests about half a year ago. A parallel_accumulate
> "practical" multithreading test was modestly slower with the
> winpthreads implementation of <thread> than with the native
> implementation; a mutex-contention test was more that an order
> of magnitude slower; and a condition-variable test was significantly
> Please let me know if you would like any follow-up information.
> Happy Threading!
> K. Frank
Thanks for the mail, it confirms a lot of what I thought based on some
basic research and zero experience of Windows threading :)
More information about the Libstdc++