【问题标题】:STL containers and threads (concurrent writes) in LinuxLinux 中的 STL 容器和线程(并发写入)
【发布时间】:2011-11-01 17:08:58
【问题描述】:

我正在寻找使用 STL 容器(如 std::map 和 std::vector)和 pthread 的最佳策略。

什么是规范的方法?一个简单的例子:

std::map<string, vector<string>> myMap;

我们如何保证并发?

mutex_lock;
write at myMap;
mutex_unlock;

另外,我想知道 pthread 和 STL 在一起使用时是否会遇到性能问题。

系统:Liunx、g++、pthreads、无增强、无 Intel TBB

【问题讨论】:

    标签: c++ linux stl concurrency pthreads


    【解决方案1】:

    C++03 标准根本没有讨论并发,所以并发方面作为编译器的实现细节被忽略了。因此,编译器随附的文档是人们应该寻找与并发相关的答案的地方。

    大多数 STL 实现本身都不是线程安全的。

    由于 STL 容器不提供任何明确的线程安全,所以是的,您必须使用自己的同步机制。而当您使用它时,您应该使用 RAII 而不是手动管理同步资源(互斥解锁等)。

    您可以在此处参考文档:

    MSDN:

    如果一个线程正在写入单个对象,则必须保护同一线程或其他线程上对该对象的所有读取和写入。例如,给定一个对象 A,如果线程 1 正在写入 A,则必须阻止线程 2 读取或写入 A。

    GCC Documentation 说:
    我们目前使用线程安全的SGI STL定义,它声明:

    STL 的 SGI 实现是线程安全的,仅在对不同容器的同时访问是安全的,对共享容器的同时读取访问是安全的意义上说。如果多个线程访问单个容器,并且至少有一个线程可能写入,则用户负责确保容器访问期间线程之间的互斥。

    注意事项:GCC 的标准库是 SGI 的 STL 代码的派生。

    【讨论】:

    • RAII 是个好主意,但是当我将元素 push_back 到我的向量时这是否适用?
    • @cateof: 是的,如果在您调用 push_back 时其他线程正在从您的向量中读取数据,那么这是一个问题。所以是的,它适用。
    【解决方案2】:

    提供并发的规范方法是在访问集合时持有锁。

    这适用于 90% 的情况,即对集合的访问无论如何都不是性能关键。如果您访问共享集合的次数过多以至于锁定它会损害性能,那么您应该重新考虑您的设计。 (很有可能,您的设计还可以,并且不会像您想象的那样影响性能。)

    【讨论】:

      【解决方案3】:

      您应该查看英特尔线程构建块 tbb (http://threadingbuildingblocks.org/)。他们有一些非常优化的数据结构,可以使用非阻塞策略在内部处理并发。

      【讨论】:

      • @Micheal,我的错。我们不能使用 TBB 中的 concurrent_vector。我会更新我的问题
      猜你喜欢
      • 2012-10-07
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      • 2011-02-02
      • 2011-12-07
      • 2018-04-05
      • 1970-01-01
      相关资源
      最近更新 更多