Подтвердить что ты не робот

Возможно ли создать атомный вектор или массив в С++?

У меня есть код, который использует массив int (int[]) в потоке, который активируется каждую секунду.

Я использую lock() из std::mutex, чтобы заблокировать этот массив в этом потоке.

Однако мне интересно, есть ли способ создать атомный массив (или вектор), чтобы избежать использования мьютекса? Я пробовал пару способов, но компилятор всегда так жалуется?

Я знаю, что есть способ создать массив атомиз, но это не то же самое.

4b9b3361

Ответ 1

На практике на уровне ЦП есть инструкции, которые могут атомизировать обновление int, и хороший компилятор будет использовать их для std::atomic<int>. Напротив, нет инструкций, которые могут атомизировать обновление вектора ints (для любой архитектуры, о которой я знаю), поэтому где-то должен быть какой-то мьютекс. Вы могли бы также позволить этому быть вашим мьютексом.


Для будущих читателей, которые еще не написали код с мьютексом:

Вы не можете создать std::atomic из int[10], потому что это приводит к функции, которая возвращает массив, и вы не можете их использовать. Что вы можете сделать, есть std::atomic<std::array<int,10>>

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

Обратите внимание, что компилятор/библиотека создаст мьютекс под капотом, чтобы сделать этот атомный. Обратите внимание, что это не делает то, что вы хотите. Это позволяет вам установить значение целого массива атомарно.

Это не позволяет вам прочитать весь массив, обновить один элемент и написать весь массив обратно атомарно.

Чтения и записи будут индивидуально атомарными, но другой поток может попасть между чтением и записью.

Вам нужно мьютекс!

Ответ 2

Вы можете помещать массивы в атомы, но не напрямую. Как и в другом ответе, вы можете использовать std::array. Я ответил на этот вопрос и объяснил, как сделать что-то подобное для структуры.

Сказав это и объяснив техническую жизнеспособность, я должен сказать вам что-то еще:

ПОЖАЛУЙСТА, НЕ ДЕЛАЙТЕ ЭТО

Сила атомных переменных исходит из того, что некоторые процессоры могут выполнять свои операции с одной инструкцией. Компилятор С++ попытается сделать ваши атомные операции в одной инструкции. Если это не удается, оно инициирует блокировку шины, которая похожа на глобальную блокировку всего, пока этот массив не будет обновлен. Это эквивалентно мьютеку, который блокирует все ваши переменные в вашей программе. Если вас беспокоит производительность, не делайте этого!

Итак, для вашего случая, мьютекс - неплохая идея. По крайней мере, вы можете контролировать, что важно, и повысить производительность.