【问题标题】:Thread-safe access to class members对类成员的线程安全访问
【发布时间】:2015-01-15 11:17:11
【问题描述】:

在 C++ 03 中同时从两个不同的 POSIX 线程访问同一对象的两个不同的类成员是否被认为是线程安全的?

【问题讨论】:

  • 在 C++ 03 中没有标准的内存模型,所以无法从 C++ 标准的角度来回答这个问题。
  • 由于它们是不同的内存位置,尽管无论内存/一致性模型如何,它都应该是线程安全的,除非线程试图在这些成员上同步。
  • @computador7 我们需要一个 C++ 中的内存模型,因为你说的不是真的 - 如果编译器不知道环境是多线程的,它会做很多类型的优化,通常涉及到触摸他们不应该在多线程环境中的内存位置。也就是说,-pthread 至少应该部分解决这个问题。
  • 你指的是什么样的优化?首先,如果您从不同的线程访问不同的内存位置,则不会出现竞争条件。现在,如果线程需要以正确的顺序查看其他线程更新,这就是内存模型规范的用武之地!接下来,我认为编译器在多线程环境中不应该触及内存位置,即使有任何内存位置,我也看不出你所指的那些优化是如何做到的!你能详细说明一下吗?
  • -pthread 链接 pthread 库和一些用于重入和线程本地存储的宏我不明白它与此有何关系。

标签: c++ multithreading thread-safety c++03


【解决方案1】:

不。(带着一点“是”的声音)

从 C++03 标准的角度来看,不存在线程之类的东西,因此不存在任何条件可以使标准将涉及并发的任何事物视为“安全”。

虽然这通常没有问题(稍加注意和适当的 C++ 范围之外的同步原语,它“无论如何都会工作”),但有一些事情需要注意,其中包括:

  • errno(和其他结构)可能不是线程本地的。 -pthread 命令行选项主要解决这个问题。
  • 类成员可以通过引用、指针或联合来相互别名,因此改变不同的成员确实可能同时改变相同的成员
  • 在没有内存模型的情况下,编译器可以(并且将!)重新排序加载和存储,这意味着例如“显而易见”的通信方式是先写入一条数据,然后设置“数据准备就绪” " 标志可能无法按预期工作。
  • 在 Windows 下,当您的程序加载 DLL 时,存在线程存在一些不立即明显的静态动态 CRT 问题。确保所有组件都“做同样的事情”(不管它是什么)。
  • 此外,某些旧版本的 CRT 可能会在每个线程中泄漏几百字节的内存(通常不是问题)。
  • 不可变对象本质上是线程安全的,来自多个线程的只读访问也是如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    相关资源
    最近更新 更多