DEV Community

Missing in Modern C++? Event Synchronization Primitive — Areg vs STL vs POCO vs Win32 API

Artak Avetyan on September 23, 2025

If you’ve ever struggled with mutexes, predicates, and spurious wakeups in C++ multithreaded code, you know how much time can be lost managing sync...
Collapse
 
dyfet profile image
David Sugar

WIndows has a native primitive for event, and it is indeed really handy. So I am curious and would have to see what the posix one looks like. But it might make my move pipelines even more efficient because I do the conditional variable / lock thing for that, though I only signal on empty or when becoming less than full, and keep separate conditions for each side of the pipeline. Another kind of primitive I have found useful and emulate from go is the waitgroup.

Collapse
 
aregtech profile image
Artak Avetyan

On POSIX, the implementation is built on top of pthread_cond + pthread_mutex — no need to reinvent the wheel. You can check it in framework/areg/base/private/posix.

What makes it different is the semantics: it supports both auto-reset and manual-reset modes, plus it integrates with a multi-wait mechanism. That means you can wait not just on multiple events, but also mix different sync objects (Event, Mutex, Semaphore) and choose whether to wake on any or on all signals.

The behavior is consistent across Windows and Linux, so you get the same API on both platforms. The multi-wait feature is conceptually close to Go’s waitgroups, but with the added flexibility of handling heterogeneous synchronization objects.

Collapse
 
dyfet profile image
David Sugar

Then what this really tells me is that if I want to rebuld pipeline on windows optimally I might want to use event rather than emulating the Posix pattern with monitor (what in effect using C++ condition_variable and mutex does), and which is what I would normally have done. So I could simply use this if I was targetting both. And yes, I can then see how this would be easier to later target HPX too.

I do tend to put a lot of my sync code right up front in my stuff because I am targeting C++ threading rather than platform primitives directly. But I also primarily focus on Posix, and the C++ thread std closely follows that. Its also why I use mingw with Posix mode runtime in a cross-build from Debian (or Alpine) to target windows rather than do so natively on VS.MSVC.

None of these choices are at all wrong. My choice was to narrow and simplify the platform scope rather than abstract and better optimize for each target platform.

Thread Thread
 
aregtech profile image
Artak Avetyan

Got it, that makes sense. My path was a bit different -- I started on Windows, looking for a clean, reliable multithreading solution. Most options were too generic or heavy, so I built a small framework on Win32 APIs. Once it worked, I extended it to IPC and ported it to POSIX -- which is why some objects on POSIX mirror Windows behavior.

Areg is lightweight enough to run even on embedded systems. My goal is to maintain the same logic across all OSes, including RTOS in the next version. Because Areg doesn’t depend on where services are located, developers can simulate microservices of the Data Layer locally while running the rest of the stack in separate processes -- a huge advantage when debugging multithreading or multiprocessing in embedded environments.

There’s also an ongoing project for development, testing, and analysis tools to help devs build and test Areg based apps faster. I have a clear and concrete vision for what features these tools should include. My resources are limited, so any support -- even just helping grow the community -- is highly appreciated.

Thread Thread
 
dyfet profile image
David Sugar

For me, this actually makes the question of participation easier in some ways. There is less overlap in what I was doing with busuto and moderncli than I had initially thought, as I had been focused on optomizing posix uses in my services, and yet is yet actually closer to what I was originally doing and had wanted to do long ago with GNU uCommon and Coomon C++.

I could split and do areg specific / adapted versions of things under apache licensing, and continue the specialized ones I am using for my existing services, too, and some of those services may make more sense to migrate to areg for portability anyway later, too. That I think could work out okay for what I was originally doing. I was of course also happy areg built fine for me on Alpine ;).

I think for me, in addition to some testing, and also looking at the tooling repo, is to start posting discussion items on the github. I will probably be ready to post discussion items later this week. Right now I am in the middle of some internal wrestling with my local gitea setup, and then I want to think thru a little bit more planning ;).

Thread Thread
 
aregtech profile image
Artak Avetyan • Edited

I’m glad to hear you successfully built and ran Areg on Alpine -- another confirmation of its minimal dependencies. :)

I’m really interested in your plans and how you envision splitting or adapting your projects for Areg. If there’s any way I can contribute to planning, testing, design, or development -- I’d be happy to help. Looking forward to your discussion items on GitHub when you’re ready!

P.S. Added another example 29_synchevent: shows that an auto-reset event never loses its signal. If set while no thread is waiting, the signal is preserved until one thread consumes it.