web-dev-qa-db-fra.com

Est-il possible de créer un vecteur atomique ou un tableau en C ++?

J'ai du code qui utilise un tableau d'int (int[]) Dans un thread qui est activé chaque seconde.

J'utilise lock() de std::mutex Pour verrouiller ce tableau dans ce fil.

Cependant, je me demande s'il existe un moyen de créer un tableau atomique (ou un vecteur) pour éviter d'utiliser un mutex? J'ai essayé plusieurs façons, mais le compilateur se plaint toujours d'une manière ou d'une autre?

Je sais qu'il existe un moyen de créer un tableau d'atomes mais ce n'est pas la même chose.

20
rainbow

En pratique, au niveau du processeur, il existe des instructions qui peuvent mettre à jour atomiquement un int, et un bon compilateur les utilisera pour std::atomic<int>. En revanche, il n'y a pas d'instructions qui peuvent mettre à jour atomiquement un vecteur d'entiers (pour toute architecture que je connaisse), donc il y a got to be un mutex d'une sorte quelque part. Autant le laisser être votre mutex.


Pour les futurs lecteurs qui n'ont pas encore écrit de code avec le mutex:

Vous ne pouvez pas créer un std::atomic de int[10], car cela conduit à une fonction qui retourne un tableau - et vous ne pouvez pas les avoir. Ce que vous pouvez faire, c'est avoir un std::atomic<std::array<int,10>>

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

Notez que le compilateur/bibliothèque va créer un mutex sous le capot pour rendre ce atomique. Notez en outre que cela ne fait pas ce que vous voulez. Il vous permet de définir la valeur de l'ensemble du tableau de manière atomique.

Il ne vous permet pas de lire tout le tableau, de mettre à jour un élément et de réécrire atomiquement l'ensemble du tableau.

Les lectures et les écritures seront individuellement atomiques, mais un autre thread peut se placer entre la lecture et l'écriture.

Vous avez besoin du mutex!

41
Martin Bonner

Vous pouvez mettre des tableaux en atomique, mais pas directement. Comme dans l'autre réponse, expliquez que vous pouvez utiliser std::array. J'ai répondu cette question et expliqué comment faire quelque chose de similaire pour une structure.

Cela dit et expliqué la viabilité technique, je dois vous dire autre chose:

VEUILLEZ NE PAS FAIRE CELA

La puissance des variables atomiques vient du fait que certains processeurs peuvent effectuer leurs opérations avec une seule instruction. Le compilateur C++ essaiera de réaliser vos opérations atomiques en une seule instruction. En cas d'échec, il initiera un verrou de bus , qui est comme un verrou global de tout, jusqu'à ce que ce tableau soit mis à jour. C'est équivalent à un mutex qui verrouille toutes vos variables dans votre programme. Si vous êtes préoccupé par les performances, ne faites pas ça!

Donc pour votre cas, un mutex n'est pas une mauvaise idée. Au moins, vous pouvez contrôler ce qui est essentiel et améliorer les performances.

6