I'm trying to find the equivalent of a critical section for C++11 , is the new C++11 mutex concept process-bound (e.g. enforces mutex only on the user-space) ? Perhaps it's implementation specific since I cannot find anything specific on it. Perhaps C++11 have their own critical section classes as mutexes are cross-process, right? Please help.
A standard library implementation is free to use any mutex implementation it likes that meets the requirements and behaviors set forth in the standard. An implementation that provides cross-process locking - which the standard doesn't require - would likely be less performant than one that does not. A high-quality implementation will therefore most likely provide process-local mutexes (mutices?).
So although one could bang out a conformant implementation of C++11 mutexes using, e.g., named semaphores, one would have a hard time selling that implementation to users. To my knowledge no popular implementation exists that provides cross-process locking in std::mutex.
The C++ standard only concerns single programs, thus a single
process; it has nothing to say about what happens outside of the
process. At least under some Posix implementations, some "mutex"
are cross-process, so under them, any C++ mutex will also be
cross-process. Under other systems, it probably depends on the
system.
Also: implementing the mutex in user space doesn't mean that it
can't be cross-process, since user space can include shared
memory or mmaped space, which is accessible from several
processes.
Related
So I'm reading about monitors vs mutexes and finding mentions that suggest that monitors are faster mutexes because they don't lock system wide but rather only across the threads of a given process.
Is there some way in C++ to accomplish or simulate this?
Edit: I'm curious now what the difference is between system wide mutex and one restricted to a specific process.
C++ Standard does not define system-wide vs per-process primitives. So C++ does not specify whether std::mutex is system-wide.
Reasonable implementations have efficient per-process std::mutex; to have system-wide mutex you'll need to use libraries or operating system objects for your platform
The difference is that per-process mutex may use any memory operations to avoid system calls, as the process memory is shared among process's threads. Atomic operation on that memory are more efficient, and system call is often avoided via them. System-wide mutex will either start with system calls (not efficient), or will have to use shared memory (might be unsafe, also still may have some overhead).
The answer by #Alex Guteniev is as accurate as one can get (and should be considered the accepted answer). It states that the c++ standard doesn't define a system wide concept, and that mutexes for all practical purposes are per process i.e for synchronization between threads (execution agents) in a single process (and therefore according to your needs). The C++ makes it clear what a thread (std::thread) is (33.3 - ... intended to map one-to-one with OS threads (in my draft, at least...N4687)).
Microsoft post VC2015 has improved their implementation to use windows primitives as stated here. This is also indicated here in the most upvoted answer. I've also looked at the boost library implementations (which often precedes/influences the c++ standard) for microsoft and (AFAICT) it doesn't use any inter-process calls.
So to answer your question. In C++ threads and monitors are practically the same thing if this definition is to be considered accurate.
Update, stumbled across the answer to this while researching something related.
On Windows, Critical Sections can be used for single processes instead of system wide mutexes and are often faster:
Edit:
While the above statement is correct, c++ doesn't have the concept system wide mutex. This concept only exists when using OS specific primitives such as win32 CreateMutex and is not relevant to std c++.
Source:
std::mutex performance compared to win32 CRITICAL_SECTION
On Linux, pthreads are for processes.
I have multiple threads simultaneously calling push_back() on a shared object of std::vector. Is std::vector thread safe? Or do I need to implement the mechanism myself to make it thread safe?
I want to avoid doing extra "locking and freeing" work because I'm a library user rather than a library designer. I hope to look for existing thread-safe solutions for vector. How about boost::vector, which was newly introduced from boost 1.48.0 onward. Is it thread safe?
The C++ standard makes certain threading guarantees for all the classes in the standard C++ library. These guarantees may not be what you'd expect them to be but for all standard C++ library classes certain thread safety guarantees are made. Make sure you read the guarantees made, though, as the threading guarantees of standard C++ containers don't usually align with what you would want them to be. For some classes different, usually stronger, guarantees are made and the answer below specifically applies to the containers. The containers essentially have the following thread-safety guarantees:
there can be multiple concurrent readers of the same container
if there is one writer, there shall be no more writers and no readers
These are typically not what people would want as thread-safety guarantees but are very reasonable given the interface of the standard containers: they are intended to be used efficiently in the absence of multiple accessing threads. Adding any sort of locking for their methods would interfere with this. Beyond this, the interface of the containers isn't really useful for any form of internal locking: generally multiple methods are used and the accesses depend on the outcome of previous accesses. For example, after having checked that a container isn't empty() an element might be accessed. However, with internal locking there is no guarantee that the object is still in the container when it is actually accessed.
To meet the requirements which give the above guarantees you will probably have to use some form of external locking for concurrently accessed containers. I don't know about the boost containers but if they have an interface similar to that of the standard containers I would suspect that they have exactly the same guarantees.
The guarantees and requirements are given in 17.6.4.10 [res.on.objects] paragraph 1:
The behavior of a program is undefined if calls to standard library functions from different threads may introduce a data race. The conditions under which this may occur are specified in 17.6.5.9. [ Note: Modifying an object of a standard library type that is shared between threads risks undefined behavior unless objects of that type are explicitly specified as being sharable without data races or the user supplies a locking mechanism. —endnote]
... and 17.6.5.9 [res.on.data.races]. This section essentially details the more informal description in the not.
I have multiple threads simultaneously calling push_back() on a shared object of std::vector. Is std::vector thread safe?
This is unsafe.
Or do I need to implement the mechanism myself to make it thread safe?
Yes.
I want to avoid doing extra "locking and freeing" work because I'm a library user rather than a library designer. I hope to look for existing thread-safe solutions for vector.
Well, vector's interface isn't optimal for concurrent use. It is fine if the client has access to a lock, but for for the interface to abstract locking for each operation -- no. In fact, vector's interface cannot guarantee thread safety without an external lock (assuming you need operations which also mutate).
How about boost::vector, which was newly introduced from boost 1.48.0 onward. Is it thread safe?
Docs state:
//! boost::container::vector is similar to std::vector but it's compatible
//! with shared memory and memory mapped files.
I have multiple threads simultaneously calling push_back() on a shared object of std::vector. ... I hope to look for existing thread-safe solutions for vector.
Take a look at concurrent_vector in Intel's TBB. Strictly speaking, it's quite different from std::vector internally and is not fully compatible by API, but still might be suitable. You might find some details of its design and functionality in the blogs of TBB developers.
I am looking for the optimal strategy to use STL containers (like std::map and std::vector) and pthreads.
What is the canonical way to go? A simple example:
std::map<string, vector<string>> myMap;
How do we guarantee concurrency?
mutex_lock;
write at myMap;
mutex_unlock;
Additionally, I would like to know if pthreads and STL face performance issues when used together.
System: Liunx, g++, pthreads, no boost, no Intel TBB
The C++03 Standard does not talk about concurrency at all, So the concurrency aspect is left out as an implementation detail for compilers. So the documentation that comes with your compiler is where one should look to for answers related to concurrency.
Most of the STL implementations are not thread safe as such.
Since STL containers do not provide any explicit Thread safety, So yes you will have to use your own synchronization mechanism. And while you are at it You should use RAII rather than manage the synchronization resource(mutex unlock etc) manually.
You can refer the Documentations here:
MSDN:
If a single object is being written to by one thread, then all reads and writes to that object on the same or other threads must be protected. For example, given an object A, if thread 1 is writing to A, then thread 2 must be prevented from reading from or writing to A.
GCC Documentation says:
We currently use the SGI STL definition of thread safety, which states:
The SGI implementation of STL is thread-safe only in the sense that simultaneous accesses to distinct containers are safe, and simultaneous read accesses to to shared containers are safe. If multiple threads access a single container, and at least one thread may potentially write, then the user is responsible for ensuring mutual exclusion between the threads during the container accesses.
Point to Note: GCC's Standard Library is a derivative of SGI's STL code.
The canonical way to provide concurrency is to hold a lock while accessing the collection.
That works in 90% of the cases where access to the collection isn't performance-critical anyway. If you're accessing a shared collection so much that locking around it harms performance, you should rethink your design. (And odds are, your design is okay and it won't affect performance anywhere near as much as you might suspect.)
You should take a look at intel thread building blocks tbb ( http://threadingbuildingblocks.org/ ). They have a few very optimized data structures that handle concurrency internally using non-blocking strategies.
I found contradictory information on the web:
http://www.sgi.com/tech/stl/thread_safety.html
The SGI implementation of STL is thread-safe only in the sense that
simultaneous accesses to distinct containers are safe, and
simultaneous read accesses to to shared containers are safe. If
multiple threads access a single container, and at least one thread
may potentially write, then the user is responsible for ensuring
mutual exclusion between the threads during the container accesses.
http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_concurrency.html
The user-code must guard against concurrent method calls which may
access any particular library object's state. Typically, the
application programmer may infer what object locks must be held based
on the objects referenced in a method call. Without getting into great
detail, here is an example which requires user-level locks:
All library objects are safe to use in a multithreaded program as long
as each thread carefully locks out access by any other thread while it
uses any object visible to another thread, i.e., treat library objects
like any other shared resource. In general, this requirement includes
both read and write access to objects; unless otherwise documented as
safe, do not assume that two threads may access a shared standard
library object at the same time.
I bolded the imporant part - maybe I dont understand what they mean by that,when I read object state I think of STL containers
How I understand this:
both documents say the same in different manner. MS STL implementation (actually Dinkumware one) says almost the same as your quoted SGI doc. They mean that they did nothing to make STL objects (e.g. containers) thread-safe, most probably because this would add an overhead unnecessary in many single-threaded applications. Any object is thread-safe in their terms, you can read it from multiple threads.
Also docs guarantee that STL objects are not modified under the hood in some background threads.
FWIW I updated the libstdc++ docs a while ago, it now says (emphasis mine):
The user code must guard against concurrent function calls which access any particular library object's state when one or more of those accesses modifies the state.
The information you cite is not contradictory. STL libraries should be safe to be used in a multi-threaded environment (actually, I've worked with one implementation where it was not the case) but it is users' burden to synchronize access to library objects. For instance, if you create a set of ints in one thread and another set of ints in another thread and you don't share either of them among threads, you should be able to use them; if you share an instance of a set among threads, it's up to you to synch the access to the set.
STL is no more. It is superseded by the C++ Standard Library. If you use the ISO C++ and the Standard Library, you should read (a) the Standard and (b) documentation that comes with your implementation of C++.
SGI STL documentation is mostly of historical interest, unless you for some reason actually use SGI STL.
I'm using Android 2.2, which comes with a version of STLport. For some reason, it was configured to be non-thread safe. This was done using a #define _NOTHREADS in a configuration header file.
When I constructed and initialized distinct non-shared containers (e.g. strings) from different pthreads, I was getting memory corruption.
With _NOTHREADS, it looks like some low-level code in STL inside allocator.cpp doesn't do proper locking. It seems analogous to C not providing thread safety for malloc.
Does anyone know why STL might be built with _NOTHREADS by default on Android? By turning this off, I'm wondering if there may be a side effect. One thing I can think of is slightly degraded performance, but I don't see much of a choice given I'm using lots of threading.
The SGI STL
The SGI STL is the grandmother of all of the other STL implementations.
See the SGI STL docs.
The SGI implementation of STL is
thread-safe only in the sense that
simultaneous accesses to distinct
containers are safe, and simultaneous
read accesses to to shared containers
are safe. If multiple threads access a
single container, and at least one
thread may potentially write, then the
user is responsible for ensuring
mutual exclusion between the threads
during the container accesses.
G++
libstdc++ docs
We currently use the SGI STL definition of thread safety.
STLPort
STLPort docs
Please refer to SGI site for detailed
document on thread safety. Basic
points are:
simultaneous read access to the same container from within separate
threads is safe;
simultaneous access to distinct containers (not shared between
threads) is safe;
user must provide synchronization for all accesses if
any thread may modify shared
container.
General Information about the C++ Standard
The current C++ standard doesn't address concurrency issues at all, so at least for now there's no requirement that applies to all implementations.
A meaningful answer can only really apply to a specific implementation (STLPort, in this case). STLPort is basically a version of the original SGI STL implementation with improvements to its portability, so you'd probably want to start with the documentation about thread safety in the original SGI version.
Of course, the reason it is without re-entrancy is for performance: speed, less memory use, less resource uses. Presumably this is because the assumption is most client programs won't be multi-threaded.
Sun WorkShop 5.0
This is a bit old but quite informative. The bottom line is that STL only provides locks on allocators.
Strings however are referenced counted objects but any changes to their reference count is done atomically. This is only true however when passing strings around by value. Two threads holding the same reference to a single string object will need to do their own locking.
When you use e.g. std::string or similar objects, and change them from different threads, you are sharing same object between threads. To make any of the member functions you can call on string reentrant, it would mean that no other thread can affect our mem-function, and our function cannot affect any other calls in other threads. The truth is exactly the opposite, since you are sharing the same object via this pointer, which is implicitly given when calling member objects. To illustrate, equivalent to this call
std::string a;
a.insert( ... );
without using OOP syntax would be:
std::string a;
insert( &a, ... );
So, you are implicitly violating requirement that no resource is shared between function calls. You can see more here.
Hope this helps.