8
votes

Array de verrouillage sans sécurité

J'ai une bibliothèque C ++, qui supposait faire des calculs sur plusieurs threads. J'ai créé un code de threads indépendant (c'est-à-dire qu'il n'y a pas de variables partagées entre eux), à l'exception d'un tableau. Le problème est que je ne sais pas comment faire le thread-coffre-fort.

J'ai regardé mutex verrou / déverrouiller ( qmutex , comme j'utilise qt), mais ce n'est pas Ajustez pour ma tâche - tandis qu'un thread verrouille le mutex, d'autres threads attendent!

Puis j'ai lu sur std :: atomique , qui ressemblait exactement à ce dont j'avais besoin. Néanmoins, j'ai essayé de l'utiliser de la manière suivante: xxx

et il a produit une erreur de compilateur ( utilisation de la fonction supprimée 'std :: atomic :: atomic (const std :: atomique &) '). Ensuite, j'ai trouvé la solution - Utilisez une enveloppe spéciale pour std :: atomique . J'ai essayé ceci: xxx

Cette chose compile avec succès, mais quand je ne peux pas remplir le vecteur: xxx

quoi Est-ce que je fais mal? Je suppose que j'ai tout essayé (peut-être pas, de toute façon) et rien n'aidé. Y a-t-il d'autres moyens pour le partage de la matrice Thread-Safe en C ++?

D'ailleurs, j'utilise le compilateur Mingw 32bit 4.7 sur Windows.


5 commentaires

Voulez-vous une taille de taille fixe (dans la partie multithread) de éléments partagés ou tableau partagé d'éléments. Je veux dire, faire des insertions et des suppressions dans la matrice ont une place dans une partie de code multithreaded ?


La matrice a une taille fixe - je n'ai pas d'insertions ni de suppressions dans des threads.


@ahawkthomes: vous poussez_back, qui change généralement la taille ...


Eh bien, comment peut initialiser std :: vecteur sans utiliser push_back ? Désolé pour de telles questions muettes, mais je ne sais rien, mais std :: vecteur t = {0, 0, 0} - et cette approche est évidemment inutile avec une grande quantité d'articles.


En outre, comprenez-vous que vos opérations d'emballage ne sont pas des opérations atomiques .


3 Réponses :


2
votes

Vous essayez de copier un type non copié: le constructeur atomicuint64 prend un atomique par valeur.

Si vous en avez besoin pour être initialisé de atomique , il devrait alors prendre l'argument par (const) référence. Cependant, dans votre cas, il ne semble pas que vous ayez besoin d'initialiser à partir de atomique du tout; Pourquoi ne pas initialiser de uint64_t à la place?

aussi quelques points mineurs:

  • Le constructeur de copie et l'opérateur d'affectation doivent prendre leurs valeurs par const référence, pour permettre aux temporaires d'être copiés.

  • allouant le vecteur avec nouveau est une chose assez étrange à faire; Vous ne faites que ajouter un niveau supplémentaire d'indirection sans avantage.

  • Assurez-vous de ne jamais redimensionner le tableau pendant que d'autres threads pourraient y accéder.


1 commentaires

Merci beaucoup pour une explication des points mineurs, et surtout pour Const , je ne savais pas de telles bases.



1
votes

cette ligne xxx

Vous ignorez complètement l'argument que vous transmettez, vous voulez probablement que ce soit.load () et vous voulez probablement prendre des éléments de la référence de Const ne sont pas copiés. xxx

comme pour ce que vous faites, je ne sais pas si c'est correct. La modification des variables à l'intérieur de la matrice sera atomique, mais si le vecteur est modifié ou réaffecté (ce qui est possible avec push_back ), il n'y a rien à garantir que vos modifications de matrice fonctionneront entre les threads et être atomiques .


0 commentaires

6
votes

Voici une version nettoyée de votre atomicuint64 code> type: xxx pré>

et utilisez: p> xxx pré>

Ou: P>

AtomicUInt64 value(x);
myVector->push_back ( value );


1 commentaires

S'il vous plaît dites-moi comment accéder à ce vecteur? Je veux savoir ce qui est stocké dans le vecteur.