简体   繁体   English

C ++ STL对不同的容器是否是线程安全的(使用STLport实现)?

[英]Is C++ STL thread-safe for distinct containers (using STLport implementation)?

I'm using Android 2.2, which comes with a version of STLport. 我使用的是Android 2.2,它附带了一个STLport版本。 For some reason, it was configured to be non-thread safe. 出于某种原因,它被配置为非线程安全的。 This was done using a #define _NOTHREADS in a configuration header file. 这是在配置头文件中使用#define _NOTHREADS完成的。

When I constructed and initialized distinct non-shared containers (eg strings) from different pthreads, I was getting memory corruption. 当我从不同的pthreads构造和初始化不同的非共享容器(例如字符串)时,我得到了内存损坏。

With _NOTHREADS, it looks like some low-level code in STL inside allocator.cpp doesn't do proper locking. 使用_NOTHREADS,看起来在allocator.cpp中的STL中的某些低级代码不能正确锁定。 It seems analogous to C not providing thread safety for malloc. 这似乎类似于C不为malloc提供线程安全性。

Does anyone know why STL might be built with _NOTHREADS by default on Android? 有谁知道为什么在Android上默认使用_NOTHREADS构建STL? 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 SGI STL

The SGI STL is the grandmother of all of the other STL implementations. SGI STL是所有其他STL实现的祖母。

See the SGI STL docs . 请参阅SGI STL文档

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. STL的SGI实现仅在对不同容器的同时访问是安全的意义上是线程安全的,并且对共享容器的同时读取访问是安全的。 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++ G ++

libstdc++ docs libstdc ++ docs

We currently use the SGI STL definition of thread safety. 我们目前使用SGI STL定义的线程安全性。

STLPort STLPort的

STLPort docs STLPort文档

Please refer to SGI site for detailed document on thread safety. 有关线程安全的详细文档,请参阅SGI站点。 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. 如果任何线程可以修改共享容器,则user必须为所有访问提供同步。

General Information about the C++ Standard 有关C ++标准的一般信息

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. 当前的C ++标准根本不解决并发问题,因此至少目前没有要求适用于所有实现。

A meaningful answer can only really apply to a specific implementation (STLPort, in this case). 有意义的答案只能真正适用于特定的实现(在本例中为STLPort)。 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. STLPort基本上是原始SGI STL实现的一个版本,并且对其可移植性进行了改进,因此您可能希望从原始SGI版本中的线程安全文档开始。

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 Sun WorkShop 5.0

This is a bit old but quite informative. 有点旧,但信息量很大。 The bottom line is that STL only provides locks on allocators. 底线是STL仅提供对分配器的锁定。

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 eg std::string or similar objects, and change them from different threads, you are sharing same object between threads. 当您使用例如std :: string或类似对象,并从不同的线程更改它们时,您将在线程之间共享相同的对象。 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. 要创建任何可以在字符串重入上调用的成员函数,这意味着没有其他线程可以影响我们的mem函数,并且我们的函数不会影响其他线程中的任何其他调用。 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: 不使用OOP语法将是:

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. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM