C++线程安全摘要

deu*_*ger 5 c++ multithreading thread-safety c++11

我想根据当前标准和C++ 0x以及实际情况(一般来说,在我的情况下使用gcc 4.5.1)总结C++中的线程安全.

对于STL容器,我的理解是根据当前标准不保证线程安全.虽然在实践中它们对于单个作者,多个读者使用(在gcc和可能是大多数现代编译器上)是线程安全的,但这是真的吗?这是由C++ 11保证的吗?

POD类型怎么样?我知道标准保证什么都没有,但我被告知在实践中,所有这些都是读写的线程安全.当然,即使是像增量运算符那样简单的东西仍然需要同步,因为可能存在多次读取和写入.

我主要对答案感兴趣,但是为什么答案背后的原因会受到赞赏.

Pet*_*man 6

您提到的所有内容都不是线程安全的,无论是标准还是实践.

标准不强制要求线程安全的原因是线程安全带来固有成本.一般来说,C++试图不向你提供你不需要的东西.如果你想要线程安全,那么你必须自己构建它.即使在包含各种同步原语的C++ 0x中也是如此.

这些东西在实践中不是线程安全的原因是多种多样的.通常,STL容器不是线程安全的,因为它们的每个基本更新操作都需要多个步骤来完成.如果某个线程在另一个线程正在更新它时尝试读取或更新容器,则该容器将处于不确定状态,因此结果将是不可预测的.

在POD类型的情况下,读取和写入也可以采取多个步骤来完成.这个最简单的例子是32位机器上的64位整数.至少需要两条指令来读取或设置值.再一次,这意味着如果一个线程试图读取或更新该值而另一个线程正在更新它,则结果将是不可预测的.


Jer*_*fin 1

当前的标准在任何方面都根本没有提到线程。实际上,标准容器提供线程安全的读取,但需要同步写入。

C++ 0x 没有太多(根本?)专门讨论关于线程安全/共享的容器,但确实讨论了赋值等。最后,结果几乎是一样的——即使对象位于容器中,您正在读取/写入数据,并且当/如果至少一个线程可以修改数据时,您必须进行同步。

POD 数据实际上并没有太大变化:作为一般规则,修改需要同步。通常有一些数据类型子集,其操作通常是原子的,但该子集的成员因平台而异。它通常包括分配有“自然”对齐的硬件本机字大小的类型;其他任何事情都有更多问题。