2

我知道在 Java 中,从另一个线程访问成员时不能保证成员的可见性。

意思是访问线程可能会看到成员的窃取值(因为缓存尚未刷新到主内存)。

我想知道 C++ 是否也是这种情况?(也在 C++11 中?)

如果是这样,你如何在 C++ 中解决这个问题?(在 Java 中,您可以使用 synchronized 关键字)。

4

3 回答 3

2

您可以std::atomic<T>用作成员的类型。这保证了一组原子操作,例如 fetch 和 increment。这通常比添加互斥锁要好得多,因为这些操作是通过 CPU 的特殊原子指令实现的

于 2014-04-01T23:41:30.957 回答
1

线程的可见性是线程而不是语言的普遍问题。在 C++ 中,可见性问题是由于错误的逻辑造成的,这是一个代码可以在没有任何问题的情况下运行,而无需对正在访问的资源或值实现互斥锁,如果逻辑有效,则代码将编译并运行而没有任何问题,但值预期的可能不是你想要的。

为了解决这个问题,您使用了 Mutex 对象并锁定正在访问的变量。但是C++11使用std::atomic. atomic 变量是一个标志,它封装了 Mutex 行为并使您免于调用 lock 和 unlock。

于 2014-04-01T23:45:28.670 回答
0

C++(不是 11)本身不支持并发,它是由扩展提供的。我主要使用的两个是 OpenMP 和 pthreads。事物的可见性和原子性取决于您使用的扩展。

  • OpenMP 用于#pragma omp barrier同步线程。它还具有“指令”,例如atomic限制critical对事物的访问。
  • pthreads 在某些功能上同步,请参阅本页的第 4.11 节以查看哪些功能导致同步。差不多:如果你使用互斥体,你就可以了。
  • 对于 C++11,请参阅本页底部,您可能会在那里找到一些有用的东西,但我在 C++11 并发方面的工作还不够多说。

关键是,同步性基于您使用的多线程扩展。

除了上述内容之外,如果您正在进行科学工作,还有 OpenMP,它具有显式线程之间的所有数据传输,因此无需担心。

于 2014-04-02T00:19:38.163 回答