我目前正在参与使用C ++开发的项目。最近我们正在考虑用一些STL等价物替换一些自定义的线程安全容器以获得一些效率。
然而,在寻找一段时间之后,我发现在STL中根本没有提供线程安全的容器,这非常令人惊讶。有什么理由吗?
答案 0 :(得分:6)
可能因为它实际上并不是那么有用(除了@Luchian Grigore在另一个答案中所说的)。即使单个容器操作是线程安全的,您仍然需要做很多工作来确保线程安全。例如,即使容器本身是线程安全的,这个简单的代码也包含竞争条件:
if (!container.empty())
container.pop();
答案 1 :(得分:4)
标准库容器确实提供了一些基本的线程安全性,对于标准库容器的设计者而言,性能是比安全性更重要的设计目标。
所有标准图书馆容器保证:
来自同一容器的多个并发读取是安全的,但是
如果至少有一个编写器线程,则没有线程安全&不得有任何其他作家或读者。
标准库容器主要设计用于在单线程环境中高效工作,并且仅提供基本线程安全性是确保不需要并发访问的容器的完全性能的一种方法。
基本线程安全需要用户需要某种同步方法以通过使用互斥锁或锁来避免竞争条件。锁定或其他形式的同步通常很昂贵,因此在不必要时需要避免。
此外,鉴于标准库容器公开的接口,容器的客户端或用户很容易通过使用锁获取和释放包装底层容器操作来提供必要的锁定(如果预期用于多个 - 线程环境。
请注意,所有实现都符合C ++标准指定的以下要求:
17.6.3.10共享对象和库[res.on.objects]
如果从不同线程调用标准库函数可能引入数据争用,则程序的行为是未定义的。可能发生这种情况的条件在17.6.4.8中规定。 [注意:修改线程之间共享的标准库类型的对象会冒未定义的行为,除非将该类型的对象明确指定为可共享而没有数据争用或用户提供锁定机制。 - 后注]
答案 2 :(得分:2)
因为线程安全是高度平台和编译器特定的。
答案 3 :(得分:1)
C ++ STL提供了几乎所有其他提供的线程安全性:只要在一个线程中没有访问对象而另一个线程是或者可能是,则可以安全地使用来自多个线程的STL容器修改它。
答案 4 :(得分:0)
在一句话中 - 因为它很难。
因为线程安全的容器需要特定的设计 - 例如他们必须是persistent data structures。这些容器最容易在功能/垃圾收集/基于事件的环境中实现。哪个C ++不是。
也就是说,实现这些仍然需要用户处理所有资源分配/解除分配。这种情况违背了收藏的重点。