我想要总结一下根据当前标准和C++0x以及在实践中C++中到底什么是线程安全(一般来说,在我的例子中也是如此,对于我使用的是gcc 4.5.1)。
对于STL容器,我的理解是,根据当前的标准,线程安全性不能得到保证。但在实践中,它们对于单个编写器、多个读取器的使用是线程安全的吗(在gcc上,可能还有最现代的编译器上)?这是由C++11保证的吗?
POD类型呢?我知道这个标准不能保证任何东西,但有人告诉我在实践中,所有的读写都是线程安全的。当然,即使是像增量操作符这样简单的操作也可能需要同步,因为可能会有多次读写。
我主要对答案感兴趣,但答案背后的原因将不胜感激。
发布于 2011-03-22 01:42:26
当前的标准在任何方面都没有提到线程化。在实践中,标准容器提供线程安全读取,但需要同步才能写入。
C++ 0x不会说太多话(完全没有?)特别是关于线程安全/共享的容器,但确实谈到了赋值之类的。最后,结果大同小异--尽管对象在容器中,但您正在读/写数据,并且必须在至少有一个线程可以修改数据时/如果可以修改数据时进行同步。
POD数据实际上不会有太多变化:修改通常需要同步。通常有一些数据类型的子集,其操作通常是原子的,但该子集的成员因平台而异。它通常会包括使用“自然”对齐分配的硬件的本机字大小的类型;其他任何类型都会有更多的问题。
发布于 2011-03-22 01:45:28
无论是在标准上还是在实践中,您提到的所有事情都不是线程安全的。
这些标准没有强制要求线程安全的原因是线程安全伴随着固有的成本。一般来说,C++尽量不给你不需要的东西。如果你想要线程安全,那么你必须自己构建它。即使在包含各种同步原语的C++ 0x中也是如此。
这些东西在实践中不是线程安全的原因是多种多样的。通常,STL容器不是线程安全的,因为它们的每个基本更新操作都需要多个步骤才能完成。如果一个线程试图读取或更新一个容器,而另一个线程正在更新它,容器将处于不确定状态,因此结果将是不可预测的。
对于POD类型,读取和写入也可能需要多个步骤才能完成。这个最简单的例子是32位机器上的64位整数。读取或设置该值至少需要两条指令。再一次,这意味着如果一个线程试图读取或更新值,而另一个线程正在更新它,结果将是不可预测的。
发布于 2011-03-22 01:42:03
POD和Standard定义的类型没有任何线程安全性。完全由代码用户来同步他们的线程以确保不会发生任何不好的事情。
在C++0x中,我几乎不知道;不是真的在检查标准的那个方面。
https://stackoverflow.com/questions/5381364
复制相似问题