Reader / Writer Lock with timeout using conditional variable - c++

How to write a Reader/Writer lock with timeout, using conditional variables in C/C++?

If you're just looking for a library, Boost.Thread might do what you want.

You may take a look at the source of Java's implementation ReentrantReadWriteLock.
Just grab the JDK unpack the src.zip file and search for the source.

There is no support for such things in current standard C++, although C++0x will have some threading support (I haven't checked to see how much). Therefore, any answer would have to be platform-dependent, using platform in a very general sense.
It is possible to write libraries that will behave similarly across different underlying systems, and there are quite a few cross-platform libraries. (These are subject to inefficiencies, of course, if the capabilities of the underlying platforms are different.) There could be a generally accepted C++ threading library that would work on Windows and Unix-based systems (which is almost anything you'd be running on a desktop nowadays), but I don't know of one offhand.
Therefore, this question can't really be answered as asked. It would be necessary to answer it on a particular platform or library, and none is specified. It would make sense if coupled with a request for a library recommendation.

Take a look at the Boost.Thread library. Specifically: shared_mutex and upgradeable_mutex objects.

Related

How to find Boost libraries that does not contain any platform specific code

For our current project, we are thinking to use Boost framework.
However, the project should be truly cross-platform and might be shipped to some exotic platforms. Therefore, we would like to use only Boost packages (libraries) that does not contain any platform specific code: pure C++ and that's all.
Boost has the idea of header-only packages (libraries).
Can one assume that these packages (libraries) are free from platform specific code?
In case if not, is there a way to identify these kind of packages of Boost?
All C++ code is platform-specific to some extent. On the one side, there is this ideal concept of "pure standard C++ code", and on the other side, there is reality. Most of the Boost libraries are designed to maintain the ideal situation on the user-side, meaning that you, as the user of Boost, can write platform-agnostic standard C++ code, while all the underlying platform-specific code is hidden away in the guts of those Boost libraries (for those that need them).
But at the core of this issue is the problem of how to define platform-specific code versus standard C++ code in the real world. You can, of course, look at the standard document and say that anything outside of it is platform-specific, but that's nothing more than an academic discussion.
If we start from this scenario: assume we have a platform that only has a C++ compiler and a C++ standard library implementation, and no other OS or OS-specific API to rely on for other things that aren't covered by the standard library. Well, at that point, you still have to ask yourself:
What compiler is this? What version?
Is the standard library implementation correct? Bug-free?
Are those two entirely standard-compliant?
As far as I know, there is essentially no universal answer to this and there are no realistic guarantees. Most exotic platforms rely on exotic (or old) compilers with partial or non-compliant standard library implementations, and sometimes have self-imposed restrictions (e.g., no exceptions, no RTTI, etc.). An enormous amount of "pure standard C++ code" would never compile on these platforms.
Then, there is also the reality that most platforms today, even really small embedded systems have an operating system. The vast majority of them are POSIX compliant to some level (except for Windows, but Windows doesn't support any exotic platform anyways). So, in effect, platform-specific code that relies on POSIX functions is not really that bad since it is likely that most exotic platforms have them, for the most part.
I guess what I'm really getting at here is that this pure dividing line that you have in your mind about "pure C++" versus platform-specific code is really just an imaginary one. Every platform (compiler + std-lib + OS + ext-libs) lies somewhere along a continuum of level of support for standard language features, standard library features, OS API functions, and so on. And by that measure, all C++ code is platform-specific.
The only real question is how wide of a net it casts. For example, most Boost libraries (except for recent "flimsy" ones) generally support compilers down to a reasonable level of C++98 support, and many even try to support as far back as early 90s compilers and std-libs.
To know if a library, part of Boost or not, has wide enough support for your intended applications or platforms, you have the define the boundaries of that support. Just saying "pure C++" is not enough, it means nothing in the real world. You cannot say that you will be using C++11 compilers just after you've taken Boost.Thread as an example of a library with platform-specific code. Many C++11 implementations have very flimsy support for std::thread, but others do better, and that issue is as much of a "platform-specific" issue as using Boost.Thread will ever be.
The only real way to ever be sure about your platform support envelope is to actual set up machines (e.g., virtual machines, emulators, or real hardware) that will provide representative worst-cases. You have to select those worst-case machines based on a realistic assessment of what your clients may be using, and you have to keep that assessment up to date. You can create a regression test suite for your particular project, that uses the particular (Boost) libraries, and test that suite on all your worst-case test environments. Whatever doesn't pass the test, doesn't pass the test, it's that simple. And yes, you might find out in the future that some Boost library won't work under some new exotic platform, and if that happens you need to either get the Boost dev-team to add code to support it, or you have to re-write your code to get around it, but that's what software maintenance is all about, and it's a cost you have to anticipate, and such problems will come not only from Boost, but from the OS and from the compiler vendors too! At least, with Boost, you can fix the code yourself and contribute it to Boost, which you can't always do with OS or compiler vendors.
We had "Boost or not" discussion too. We decided not to use it.
We had some untypical hardware platforms to serve with one source code. Especially running boost on AVR was simply impossible because RTTI and exceptions, which Boost requires for a lot of things, aren't available.
There are parts of boost which use compiler specific "hacks" to e.g. get information about class structure.
We tried splitting the packages, but the inter dependency is quite high (at least 3 or 4 years ago).
In the meantime, C++11 was underway and GCC started supporting more and more. With that many reasons to use from boost faded (Which Boost features overlap with C++11?). We implemented the rest of our needs from scratch (with relative low effort thanks to variadic templates and other TMP features in C++11).
After a steep learning curve we have all we need without external libraries.
At the same time we have pondered the future of Boost. We expected the newly standardized C++11 features would be removed from boost. I don't know the current roadmap for Boost, but at the time our uncertainty made us vote against Boost.
This is not a real answer to your question, but it may help you decide whether to use Boost. (And sorry, it was to large for a comment)

Interlocked ops vs XXX::atomic on Win32

What are the advantages and disadvantages of using Interlocked winapi functions instead of any library provides atomic operations on Win32 platform?
Portability is not an issue.
If portability is not a concern then you're basically down to deciding whom you trust more to get this right. A library is generally designed to provide portability. It otherwise has a tough time competing with an OS provided implementation that's been battle-hardened for over 15 years.
Check this thread to see an example of how the obvious implementation is not in fact the best.
The Interlocked winapi functions work on old processors even when there is no CPU support for locked operations. 386 and maybe 486, not really a issue today unless you still support Win9x and older NT.
It would likely depend up on the specific atomic library in question.
A good library with a specific back-end would likely end up with the same implementation of a couple of ASM instructions to issue an x86 lock instruction and do their work. And assuming the library itself is portable, subsequently make your code portable.
A naive atomic implementation might do something heavier like use a mutex to protect a normal variable. I don't know of any that do - just making the point for argument.
As such, given your stated non-portability requirements, using the Win32 functions should be fine. Alternately, go ahead with an Atomic version, but perhaps look at the actual implementation.

Why were threads never included as part of the C++ standard?

Why is it that threads were never included as part of the C++ standard originally? Did they not exist when C++ standard was first created?
I think the main reasons are
specifying threading behavior into the language needs a lot of work and understanding, which nobody had available back then
nobody had a great idea about a good threading API, and there was no one existing library that seemed good enough to be used as a base for further work
the standardization committee was swamped with enough of other work (like incorporating the STL into the standard library)
that standard was late as it was; it took more than ten years for the first version to emerge, with quite a lot delay due to "last-minute changes" (std::auto_ptr, STL), and I think the main feeling was to better have something out sooner than to keep waiting for an infinitively delayed perfect standard; I think back then most people didn't think it would take so long for the next version to get finalized
After the standard was ratified, boost was founded by members of the library working group as a testbed for libraries which were desirable to have in the std lib but for which there wasn't enough time to make it for the final version. There, much of the work needed for adding threading support to C++ (namely inventing a good threading library) was done.
The current Standard is from 1998. There were different thread implementations, and there wasn't the body of experience with using threads that there is twelve years later. If C++ had had a standardized thread library, it would likely have worked poorly with some common thread implementations, and might well have been difficult to adapt in the future.
It's twelve years later now, and we know a whole lot more about how threads are used, and the more widespread use created more interest in standardizing them, so the upcoming C++ standard (which I hope will be official in 2011) will have a section on threads in the library.
Threads certainly did exist when C++ was being standardised during the 1990s. However, Windows and Posix have very different threading APIs. Designing a library of the quality you'd want from a standard language library, giving all the threading primitives you need and mapping well onto both popular APIs (and others), required a large effort. Including it in the initial standard would have required either delaying standardisation, possibly for years, or including a specification that may well have had significant shortcomings.
That work has been done over the last decade or so (initially as the Boost.Thread library), and will be included as the standard thread support library in the next version of the standard, in addition to language-level features such as thread-local storage.
There is a lot of work involved in creating a thread class and C++0x has largely addressed this by adding the thread, mutex and atomic libraries but it took a lot of work from a lot of folks.
Orginazationally, remember that C++ is a very large language and changes happen quite slowly to it because of the complexity of the language and the amount of code and industry that rely on it; it takes a long time to get ratify changes into the standard because of this.
Also threading and synchronization has typically been an OS provided functionality so any additions needed to be compatible with the common implementations and possible without massive changes to the platforms (or noone would be able to implement the standard).
Technically, it isn't sufficient to just add a thread API, C++ was also missing a cohesive memory model, i.e. how do variables interact across thread and how do we allow for the wide range of memory models to be expressed in code succinctly (and performantly). Most of us are fortunate enough to work on primarily single-threaded x86 based software which has a very forgiving memory model, but there is other hardware out there that is not as forgiving from a memory model perspective and where performance penalties can be quite harsh.
The library addresses the memory model issue by providing atomic variables with forgiving defaults and explicit control.
The library provides another key piece of functionality for portable threading by providing synchronization classes.
Finally was added and if you haven't read the history on the working group site, it's interesting, but simply replacing CreateThread, QueueUserWorkItem or a pthread invocation was a thread object isn't quite enough. Thread lifetime, state management and thread local storage all had to be thought through.
All of this took a long time to get right and as others have mentioned most of it was in boost for quite awhile to ensure that major issues were worked through and it was cohesive before making it into the new standard.
Because the authors didn't want to force a particular behaviour on implementers.
Threads are an OS thing, so they aren't really a function of the programming language as much as they are the libraries provided by the system. POSIX threads for example, can be used in C++ but aren't really "part" of it.
One of the challenges that was faced by the standard committee 12 years ago is the differences in the parallel hardware. A key distinguishing feature between various high performance computing architectures is the way the permit parallel computation, and only one of those many models is really similar to the posix threads abstraction, SMP.
If you compare this situation to the one faced by the Fortran language, which targets this sort of hardware specifically, you see that each vendor supplies a Fortran compiler that they have extended to support the special parallel computing features the hardware provides.
This can be seen as relevant in todays terms by comparing typical x86/x64 white box compute nodes, which usually have up to 4 sockets, which translates into 24 cores with a single shared memory to a Gaming PC with multiple nVidia or AMD GPU's. Both are capable of startling compute throughput, but to get the most out of either requires a very different programming style. In fact, different workloads will work significantly better on one architecture than the other, depending on the exact nature of the specific algorithm.
That being said, it was probably impossible, 12 years ago, for the standard committee to identify how it should address each of these issues. Now, however, the answer is much simpler. C++ is not aimed at anything besides SMP hardware; those are served by other languages and tool-chains such as OpenCL or VHDL.
Because they are OS dependent. I.E. unix/linux/macosx use pthread API, Windows use its own API, and so on and so forth...
They could have been included into libstdc++, but I guess it is not easy to include all current and future thread features on a common API. The same way, DB access is not included in libstdc++ either.

Portable C++ library for IPC (processes and shared memory), Boost vs ACE vs Poco?

I need a portable C++ library for doing IPC. I used fork() and SysV shared memory until now but this limits me to Linux/Unix. I found out that there are 3 major C++ libraries that offer a portable solution (including Windows and Mac OS X). I really like Boost, and would like to use it but I need processes and it seems like that this is only an experimental branch until now!? I have never heard of ACE or POCO before and thus I am stuck I do not know which one to choose. I need fork(), sleep() (usleep() would be great) and shared memory of course. Performance and documentation are also important criteria.
Thanks, for your Help!
Boost Interprocess has been around since Boost 1.35 (which should be something like 3 years ago if memory serves).
ACE has been around longer, but from the sound of things, it's probably overkill -- ACE is a big library, and you only seem to want a tiny bit of what it includes. That's not necessarily a major problem, but it is something to keep in mind. In particular, a library that's really designed for big projects can tend to seem (or be) a bit clumsy for smaller ones. ACE is also intended primarily for network development, with IPC included because (for example) you might want to build what appears to be a single server out of a number of cooperating processes, and if so you obviously need a way to build those cooperating processes.
POCO is a lot more like ACE -- it's basically a network library that happens to include some IPC capability. Again, you're looking at using a pretty small part of a much larger, more ambitious library.
Based on what you want, I'd probably use Boost -- it seems to be the closest fit for what you've said you want. POCO would probably be my second choice. Although it's separate from Boost, it seems to largely follow similar design philosophy -- in particular it's meant to integrate with the standard library, where ACE tends to be more all-encompassing.
I like to add the Apache portable runtime. It`s not really c++ but of course you can use it. The headers even has the "extern "C"" included.
Included is:
Shared Memory
Network connections
Signals
Mutexes
many other things.
The problem with boost is that it has strong requirements for the c++ compiler. Especially cross compilers have a problem with e.g. the strong template usage, so that a plain C library is "more portable".

C++0x threading

With the advent of threading facilities in the STL for the new C++ standard (C++0x), will it be better to change existing code that is using POSIX threading or even Windows threading to use STL threading?
You could always hedge your bets... write your own simple threading API that is just featureful enough to do what your application needs to be done, and change your code to target your threading API only. Then you can implement the internals of your custom threading API using Windows or Posix or STL or whatever, and change the implementation whenever you need to without having to touch your entire codebase each time.
By doing it that way, you could start with the STL implementation, and then if it turns out that e.g. Windows has a difficult-to-resolve problem using that, you could just include an alternate Windows-API implementation inside my_threading_api.cpp (inside of an #ifdef WIN32) and you'd be back in business.
A great deal will depend on how much you care about portability, and how much you're taking advantage of features your native API may provide that the standard library doesn't. The standard library threading is sufficiently similar to POSIX that (at least offhand) I can't think of much you'd gain by staying with POSIX (and due to the similarity, porting to use the standard library should usually be pretty easy).
Windows threading is enough different that you're more likely to run into something that will be non-trivial to port to using the standard library, and even at best porting will probably be non-trivial.
Don't change unless you really need it. I assume that your existing code is working well.
There's no telling how long it will be before the C++0x library features are commonly supported, so the answer might well depend on how tied to a particular compiler you might want to be.
You might also want to consider a framework or library that works on top of the native or C++0x library implementation, such as Boost Threads or the Intel Threading Building Blocks and let that library handle the details of whether it's using C++0x features or platform APIs.
It depends.
C++0x threading isn't widely supported yet (I think GCC implements it, but MSVC doesn't, and I don't know when they're planning to add that support, but I might suspect they consider it a low priority feature)
If your code works as it is, why change it?
For new C++ applications, and assuming compiler support, I'd go with C++0x threads, simply because they're standard, and it's a much nicer API than either Win32 or POSIX threads.