是C ++的std ::设置线程安全的?(Is the C++ std::set thread-sa

2019-06-21 08:45发布

我有个关于性病的线程安全::设置问题。

据我知道我可以遍历一组,并添加/删除成员,并且不坏的迭代器。

但考虑以下情形:

  • 螺纹“A”迭代的一组的shared_ptr <类型>
  • 线“B”偶尔将项添加到该组。

我所经历的段错误在程序运行时,我不知道为什么会这样。 缺乏线程安全的原因是什么?

Answer 1:

STL没有内置的线程支持,所以你必须用自己的同步机制扩展STL代码在多线程环境中使用STL。

例如看看这里: 链接文本

由于集是一个容器类MSDN有以下谈谈容器的线程安全。

单个对象是线程安全从多个线程读取。 例如,给定的对象A,它是安全的从线程1和线程从2同时读取。

如果一个对象正由一个线程写入,那么所有的读取和写入该对象相同或其他线程必须得到保护。 例如,给定的对象A,如果线程1被写入到A,那么线程2必须从读取或写入到A.能够防止

它是安全的读取和写入,即使另一个线程读取或写入同一类型的不同实例的类型的一个实例。 例如,给定对象A和相同类型的B,它是安全的,如果正被写入线程1 A和B在线程2被读取。



Answer 2:

该Dinkumware的STL-文件包含有关该主题的follwing段落。 它可能(如文中所述)适用于大多数实现。

对于标准C ++库中定义的容器对象,如STL容器和模板类对象basic_string,这种实现如下阐明了SGI STL广泛采用的做法:

多个线程可以安全地读取相同的容器对象。 (有容器对象内nunprotected可变子对象)。

两个线程可以安全地处理同一类型的不同容器中的对象。 (有一个容器类型内没有未保护的共享静态对象)。

如果至少一个线程正在修改的对象必须防止对容器对象同时访问。 (最明显的同步原语,如那些在鼎信线程库,将不会由容器对象破坏。)

因此,没有尝试,以确保容器对象的原子操作是线程安全的; 但它很容易足以让那些线程粒度相应级别的安全共享的容器对象。



Answer 3:

STL容器都不是线程安全的,这样std::set特别是没有的。

在你的情况,这个问题是不是就算真的线程安全,但:您只需分享在多个线程对象(罚款),并修改它在一个线程(罚款以及)。 但是,正如你已经说过,修改容器无效的迭代器。 这是否发生在同一个线程,在不同的线程是没有结果的,因为它仍然是相同的容器

D'哦! §23.1.2.8指出插入不坏迭代器。



Answer 4:

简单的解释:如果线程A通过容器移动迭代器,它看着容器内部。 如果线程B修改容器(甚至是不坏A有迭代器的操作),线程A可以,因为B与容器内部嘴硬,可能让他们在一个(暂时)无效状态遇到麻烦。 这会导致线程A崩溃

问题不在于迭代器本身。 这时候,他们需要以发现你陷入困境的位置容器的数据结构。

就那么简单。



Answer 5:

是。 处理这种情况的一种方法是让每个线程访问相同的一组对象之前锁定一个共享互斥。 请确保您使用RAII技术锁定和解锁互斥。



Answer 6:

执行插入时可使矢量重新分配其底层存储器而迭代可能仍然指向先前(但无效)存储器地址,从而导致故障段。



文章来源: Is the C++ std::set thread-safe?
标签: c++ stl std stdset