并发C ++程序的可见性

时间:2014-04-01 23:32:08

标签: java c++ multithreading c++11 memory-visibility

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

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

我想知道C ++的情况是否也是如此? (也在C ++ 11中?)

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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

线程的可见性是线程的一般问题,而不是语言。在C ++中,可见性问题是由于错误的逻辑,这是一个可以在没有任何问题的情况下运行的代码,如果逻辑有效则代码将编译并运行而没有任何问题但是值预计可能不是你想要的。

要解决此问题,您使用了Mutex对象并锁定了正在访问的变量。但 C ++ 11 使用std::atomic进一步解决了这个问题。原子变量是一个封装Mutex行为的标志,使您无需调用锁定和解锁。

答案 2 :(得分:0)

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

  • OpenMP使用#pragma omp barrier来同步线程。它还有atomiccritical等“指令”来限制对事物的访问。
  • pthreads对某些函数进行同步,请参阅section 4.11 of this page以查看哪些函数会导致同步。差不多:如果你使用互斥锁就可以了。
  • 对于C ++ 11,请参阅this page的底部,您可能会发现一些有用的东西,但我对C ++ 11并发性的说法还不够多。

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

除了上述内容,如果您正在进行科学工作,那么OpenMP会明确地在线程之间进行所有数据传输,因此没有这样的担忧。