繁体   English   中英

C ++线程安全摘要

[英]C++ Thread Safety Summary

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

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

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

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

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

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

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

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

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

C ++ 0x对于线程安全/共享方面的容器没有多少谈论(根本没有?),但确实讨论了赋值等。 最后,它几乎完全相同 - 即使对象在容器中,您正在读/写数据,并且当/如果至少一个线程可能修改数据时您必须同步。

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

POD和标准定义的类型没有任何线程安全性。 完全取决于代码用户同步其线程以确保不会发生任何不良事件。

在C ++ 0x中,我不知道; 没有真正检查标准的那个区域。

C和C ++都没有内置到语言中的并发原语(例如)java with synchronised 这是(我相信)故意 - 即使在现代版本 - 以避免在不需要时有开销。 Unix在早期并不支持轻量级进程,因此线程主要是内核问题。

各种专有线程库(例如Solaris线程)由供应商生成,并且业界最终在pthread库上进行了标准化,最初使用纯粹的用户空间线程模型(阻塞I / O等调用会阻塞所有线程)以及稍后的内核线程支持。 Windows,OS / 2和各种其他操作系统提供专有的线程功能。

C / C ++被设计为在可能有或没有线程支持的系统上运行,并且可以高效运行 - 因此线程支持是一个可选的附加功能。 C ++的设计理念之一是程序员不应该为他们不使用的功能付费。 人们可以在多核机器的时代争论这种方法的优点,但假设“整个世界都是PC” ,几十年来一直被认为是编写便携式C代码的一个主要缺陷。

尽管存在跨平台的线程库,但最终结果是线程往往是特定于平台的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM