是否有可能在c++中创建一个原子向量或数组?

时间:2022-05-26 00:55:56

I have some code which uses an array of int (int[]) in a thread which is activated every second.

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

I use lock() from std::mutex to lock this array in this thread.

我使用锁()从std::在这个线程互斥锁定这个数组。

However I wonder if there is a way to create an atomic array (or vector) to avoid using a mutex? I tried a couple of ways, but the compiler always complains somehow?

但是,我想知道是否有一种方法可以创建一个原子数组(或向量)来避免使用互斥对象?我尝试了几种方法,但是编译器总是莫名其妙地报错?

I know there is a way to create an array of atomics but this is not the same.

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

2 个解决方案

#1


29  

In practice, at the CPU level, there are instructions which can atomically update an int, and a good compiler will use these for std::atomic<int>. In contrast, there are are no instructions which can atomically update a vector of ints (for any architecture I am aware of), so there has got to be a mutex of some sort somewhere. You might as well let it be your mutex.

在实践中,在CPU级别上,有一些指令可以自动更新int,优秀的编译器会在std::atomic 中使用这些指令。相反,没有任何指令可以自动更新int向量(对于我所了解的任何体系结构),所以一定有某种互斥体。您不妨让它成为您的互斥对象。


For future readers who haven't yet written code with the mutex:

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

You can't create a std::atomic of int[10], because that leads to a function which returns an array - and you can't have those. What you can do, is have a std::atomic<std::array<int,10>>

您不能创建一个std:::atomic (int[10]),因为这会导致一个函数返回一个数组——您不能拥有这些。您可以做的是,有一个std::atomic <:array> >

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

Note that the compiler/library will create a mutex under the hood to make this atomic. Note further that this doesn't do what you want. It allows you to set the value of the whole array atomically.

请注意,编译器/库将在引擎盖下创建互斥对象,以使其具有原子性。请进一步注意,这并不是您想要的。它允许您以原子方式设置整个数组的值。

It doesn't allow you to read the whole array, update one element, and write the whole array back atomically.

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

The reads and the writes will be individually atomic, but another thread can get in between the read and the write.

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

You need the mutex!

你需要互斥锁!

#2


6  

You can put arrays in atomics, but not directly. Like the other answer explain you can use std::array. I answered this question and explained how to do something similar for a struct.

可以将数组放到atomics中,但不能直接这样做。就像另一个解释一样,你可以使用std::array。我回答了这个问题,并解释了如何为结构体做类似的事情。

Having said that and explained the technical viability, I have to tell you something else:

说了这些,并解释了技术可行性,我必须告诉你一些其他的事情:

PLEASE DON'T DO THAT

The power of atomic variables come from the fact that some processors can do their operations with one instruction. The C++ compiler will try to make your atomic operations happen in one instruction. If it fails, it'll initiate a bus lock, which is like a global lock of everything, until that array is updated. It's equivalent to a mutex that locks all your variables in your program. If you're concerned about performance, don't do that!

原子变量的强大之处在于,某些处理器可以用一条指令进行操作。c++编译器将尝试在一条指令中进行原子操作。如果失败,它将初始化一个总线锁,这就像所有东西的全局锁,直到该数组被更新。它相当于一个互斥体,锁住程序中的所有变量。如果你担心性能,不要那么做!

So for your case, a mutex is not a bad idea. At least you can control what is critical and improve performance.

所以对于你来说,互斥对象并不是一个坏主意。至少您可以控制什么是关键并提高性能。

#1


29  

In practice, at the CPU level, there are instructions which can atomically update an int, and a good compiler will use these for std::atomic<int>. In contrast, there are are no instructions which can atomically update a vector of ints (for any architecture I am aware of), so there has got to be a mutex of some sort somewhere. You might as well let it be your mutex.

在实践中,在CPU级别上,有一些指令可以自动更新int,优秀的编译器会在std::atomic 中使用这些指令。相反,没有任何指令可以自动更新int向量(对于我所了解的任何体系结构),所以一定有某种互斥体。您不妨让它成为您的互斥对象。


For future readers who haven't yet written code with the mutex:

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

You can't create a std::atomic of int[10], because that leads to a function which returns an array - and you can't have those. What you can do, is have a std::atomic<std::array<int,10>>

您不能创建一个std:::atomic (int[10]),因为这会导致一个函数返回一个数组——您不能拥有这些。您可以做的是,有一个std::atomic <:array> >

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

Note that the compiler/library will create a mutex under the hood to make this atomic. Note further that this doesn't do what you want. It allows you to set the value of the whole array atomically.

请注意,编译器/库将在引擎盖下创建互斥对象,以使其具有原子性。请进一步注意,这并不是您想要的。它允许您以原子方式设置整个数组的值。

It doesn't allow you to read the whole array, update one element, and write the whole array back atomically.

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

The reads and the writes will be individually atomic, but another thread can get in between the read and the write.

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

You need the mutex!

你需要互斥锁!

#2


6  

You can put arrays in atomics, but not directly. Like the other answer explain you can use std::array. I answered this question and explained how to do something similar for a struct.

可以将数组放到atomics中,但不能直接这样做。就像另一个解释一样,你可以使用std::array。我回答了这个问题,并解释了如何为结构体做类似的事情。

Having said that and explained the technical viability, I have to tell you something else:

说了这些,并解释了技术可行性,我必须告诉你一些其他的事情:

PLEASE DON'T DO THAT

The power of atomic variables come from the fact that some processors can do their operations with one instruction. The C++ compiler will try to make your atomic operations happen in one instruction. If it fails, it'll initiate a bus lock, which is like a global lock of everything, until that array is updated. It's equivalent to a mutex that locks all your variables in your program. If you're concerned about performance, don't do that!

原子变量的强大之处在于,某些处理器可以用一条指令进行操作。c++编译器将尝试在一条指令中进行原子操作。如果失败,它将初始化一个总线锁,这就像所有东西的全局锁,直到该数组被更新。它相当于一个互斥体,锁住程序中的所有变量。如果你担心性能,不要那么做!

So for your case, a mutex is not a bad idea. At least you can control what is critical and improve performance.

所以对于你来说,互斥对象并不是一个坏主意。至少您可以控制什么是关键并提高性能。