From: SynchronizationStrategies
While operating system provided synchronization primitives are important, they are very difficult to use properly. In Windows, they are implemented in C through Win32, which is far too low level. Although object wrappers exist in both MFC and DirectX, none are particularly well written or easy to understand.
Moreover, sometimes you want more complicated primitives than the standard set, or different behaviour from the standard set. You want to build a CactiOfConcurrency. For instance, ReaderWriterLocking.
Therefore, write your own threading package with its own synchronization primitives. Not only will it become easier to extend the primitives, but you can also prevent common errors like balancing critical section enters and leaves, simplify use and add new primitives.
But, writing your own package every time seems like a waste of effort. Buy a third party library if you must, but make sure you get source code you can understand and modify.
Someone please help me to understand. I thought that WriteYourOwnThreadingPackage was an AntiPattern. I thought that threading was a difficult thing to write, which you would never want to trust to something developed in "a few days" (quoted from below). What gives... am I wrong? -- MichaelChermside
It's not terribly difficult if you can constrain the problem. If you don't do preemption, it's very easy. In C/C++, you don't even have to drop to assembly language -- you can do it all with setjmp/longjmp.
So is that what we're talking about here... non-premptive threading?
Not necessarily. You can certainly write a complete non-preemptive, user-space threading kernel if you want. More generally, the claim includes writing your own threading library that wraps OS primitives is also good.
Check out Fibers in Windows NT/2000 --DanielEarwicker
I have written a threading package that I use almost exclusively. It came originally with its own thread class and critical section wrappers. Later, it was extended to add events and waitable timers. The benefits were tremendous to my last project.
The thread class I wrote was significantly different from MFCs CWinThread. First, it was lightweight in comparison because it didnt come with its own event loop. It was a simple Win32 thread at heart, not a window thread. Second the threads main function was not a virtual function of the thread class, but a normal C callback. While this may seem non-object-oriented, it is more powerful and reduced the tight coupling that subclassing requires. Third, the thread came with the precise functionality we needed, most of which was unavailable through MFC. It has been easy to extend the functionality of the thread class because I controlled the source code.
Also, it was easy to get the WinNT-only TryEnterCriticalSection?() behaviour on Win95/98 as it fell out of my CriticalSection implemenation. This turned out to be immensely useful.
Finally, it was also easy to add more exotic "primitives" like timer threads. -- SunirShah
Having done this myself in a previous life, I disagree. The only reason I did it was because I couldn't find one (this was a while ago) and it sucked too much time out of the project (in those days I didn't know about DoSimpleThings either). There are other sources of code than MFC. For a thread library the various free ORBs come to mind -- and if there's money involved you can buy from people like RogueWave (no endorsment intended). Generic thread packages are entertaining to write, but often you just don't get the return. --SteveFreeman
If not your own, get one you can modify the source to. The idea is that you should be able to extend the package. -- SunirShah
I also did this in a previous life. I was writing a C++ embedded system for a DOS-on-a-board. I rolled my own for one reason: I didn't need or want pre-emptive threading. I was happy to have context switches take place only where I wanted them to take place. Non-preemptive threading was powerful enough for me to write a soft real-time process controller, it's simple to write (took a few days), and it's simple to debug code that uses it.
I still do this in Java for thread-pooling. I don't know any other way of getting consistent scheduling. It still requires cooperation, but that is appropriate where performance is important, and watchdog timers can kill runaway threads if necessary. --RichardHenderson.
Hopefully you will not have to integrate with any other code, like a CORBA ORB, that needs threading beause they can't use your package. That's why a standard is nice be it posix or java. --AnonymousDonor
No problems. Usually the threading is to provide a multiclient service so no ORB's required anyway, except where clients are trying to do middleware on the cheap.