11

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.

Ravi
  • 3,718
  • 7
  • 39
  • 57
  • It might help people answer your question if you gave some sample code that showed the sort of thing that leads to the problem. (I know *I* don't have the expertise to answer this one; the STL isn't something I've studied in depth.) – Donal Fellows Dec 10 '10 at 00:04
  • What do you mean by "accessed ... objects"? – LavaScornedOven Dec 10 '10 at 00:07
  • This question's been asked before (see http://stackoverflow.com/questions/4029448/thread-safety-for-stl-queue and http://stackoverflow.com/questions/1362110/is-the-c-stl-stdset-thread-safe), but there's on one central answer to this question yet. Since this version is as good as any to become **the** central place to answer this question on StackOverflow, please use a big heading to include the name of your implementation, and quote and link to the original documentation. – Ken Bloom Dec 10 '10 at 00:56
  • Vedran - I updated "accessed" to mean "constructed and initialized" – Ravi Dec 10 '10 at 01:05

5 Answers5

5

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.
Ken Bloom
  • 57,498
  • 14
  • 111
  • 168
  • Any info about string reference counting? – doron Dec 10 '10 at 01:02
  • Interesting that STLport docs say "simultaneous access to distinct containers (not shared between threads) is safe". This feature is disabled on Android. – Ravi Dec 10 '10 at 03:48
2

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.

Community
  • 1
  • 1
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • The documentation from the above link mentions the problem I encountered: "Alloc.h uses three different locking primitives depending on the environment. In addition, it can be forced to perform no locking by defining _NOTHREADS." In the Android distribution, _NOTHREADS was defined. When I undefined it, the memory corruption problems went away. – Ravi Dec 10 '10 at 03:43
1

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.

Yttrill
  • 4,725
  • 1
  • 20
  • 29
0

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.

Ken Bloom
  • 57,498
  • 14
  • 111
  • 168
doron
  • 27,972
  • 12
  • 65
  • 103
0

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.

LavaScornedOven
  • 737
  • 1
  • 11
  • 23