并发C++程序中的可见性



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

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

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

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

您可以使用

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

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

为了解决这个问题,你使用了一个互斥对象并锁定了正在访问的变量。但是C++11通过std::atomic进一步解决了这个问题。原子变量是一个标志,它封装了互斥行为,并使您免于调用锁定和解锁。

C++(

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

  • OpenMP 使用#pragma omp barrier来同步线程。它还具有"指令",例如atomiccritical来限制对事物的访问。
  • pthreads 在某些函数上同步,请参阅本页的第 4.11 节以了解哪些函数导致同步。差不多:如果你使用互斥锁,你没问题。
  • 对于 C++11,请参阅本页底部,您可能会在那里找到一些有用的东西,但我对 C++11 并发性的工作还不够多,无法说太多。

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

除了上述内容之外,如果您正在做科学工作,还有OpenMP,它具有线程之间的所有数据传输,因此没有这样的担忧。

最新更新