是否可以在C ++中创建原子向量或数组?

时间:2017-09-06 07:33:37

标签: c++ arrays multithreading vector atomic

我有一些代码在一个每秒激活的线程中使用一个int(int[])数组。

我使用lock()中的std::mutex来锁定此主题中的数组。

但我想知道是否有办法创建原子数组(或向量)以避免使用互斥锁?我尝试了几种方法,但编译器总是以某种方式抱怨?

我知道有一种方法可以创建一个原子数组,但这不一样。

2 个答案:

答案 0 :(得分:37)

实际上,在CPU级别,有一些指令可以自动更新int,一个好的编译器会将这些指令用于std::atomic<int>。相比之下,没有任何指令可以自动更新int的向量(对于我所知道的任何架构),因此得到是某种某种互斥体。你不妨让它成为你的互斥体。

对于尚未使用互斥锁编写代码的未来读者:

您无法创建std::atomic int[10],因为这会导致返回数组的功能 - 而您无法获得这些功能。您可以做的事情是std::atomic<std::array<int,10>>

int main()
{
  std::atomic<std::array<int,10>> myArray;
}

请注意,编译器/库将在底层创建一个互斥锁以使其成为原子。进一步注意,这并不是你想要的。它允许您以原子方式设置整个数组的值。

不会允许您读取整个数组,更新一个元素,并以原子方式写回整个数组。

读取和写入将是单独原子的,但另一个线程可以介入读取和写入之间。

你需要互斥锁!

答案 1 :(得分:6)

您可以将数组放在原子中,但不能直接放入。与其他答案解释一样,您可以使用std::array。我回答this question并解释了如何为结构做类似的事情。

话虽如此并解释了技术可行性,但我必须告诉你一些事情:

请不要这样做

原子变量的力量来自于某些处理器可以用一条指令执行操作的事实。 C ++编译器将尝试在一条指令中进行原子操作。如果失败,它将启动总线锁,这类似于全局锁定所有内容,直到该阵列更新为止。它相当于一个锁定程序中所有变量的互斥锁。如果您担心表现,请不要这样做!

因此,对于您的情况,互斥量并不是一个坏主意。至少你可以控制什么是关键并提高性能。