Dans mon programme, j'ai des threads en cours d'exécution. Chaque thread obtient un pointeur sur un objet (dans mon programme - Vector). Et chaque fil modifie le vecteur. P>
Et parfois, mon programme échoue avec une faute SEGM. Je pensais que cela se produisait parce que le fil a commence à faire quelque chose avec le vecteur pendant que le fil b n'a pas fini de fonctionner avec elle? Peut-il être vrai? P>
Comment suis-je censé le réparer? Synchronisation de fil? Ou peut-être faire un drapeau vectorisinuse code> et définir ce drapeau sur true tout en fonctionnant avec celui-ci? P>
3 Réponses :
C'est pourquoi la bibliothèque de classe qui offre des threads a également des primitives de synchronisation telles que les mutexes / serrures. Vous devez configurer l'un d'entre eux, et éroger / relâcher la serrure autour de chaque opération sur l'élément partagé (options de lecture et d'écriture, puisque vous devez empêcher les lectures de l'occultation pendant une écriture aussi, n'empêchez pas seulement les écrivies multiples qui se produisent simultanément). < / p>
N'utilisez pas de drapeau car il n'est pas thread-coffre-fort: p> Notez que chaque thread devra verser le vecteur code> code> pendant tout le temps nécessaire à l'utiliser. Cela inclut la modification du vecteur code> à l'aide des itérateurs code> Vecteur code> car les itérateurs peuvent devenir invalidés si l'élément à laquelle ils se réfèrent sont vecteur code>, comme tous les conteneurs STL, ne sont pas thread-coffre-fort. Vous devez explicitement gérer la synchronisation vous-même. Un
std :: mutex code>
ou boost :: mutex code>
pourrait être utilisé pour synchroniser l'accès au vecteur code>.
isinuse code> drapeau et c'est
false code> li>
isinuse code> drapeau et c'est
false code> li>
isinuse code> à
true code> li>
isinuse code> est
false code> et le définit
true code> li>
code> li>
ul>
effacer () code> ou
vecteur code> subit une réaffectation interne. Par exemple
Méfiez-vous que les itérateurs et les références peuvent être invalidés et que vous ne pouvez pas protéger contre cela avec des mutiles.
@juanchopanza, Yep. Était toujours à jour.
Volontier. J'ai complètement mal interprété votre réponse. J'ai vu l'échantillon de code et j'étais comme "Whaaa Epic Fil!". Ensuite, j'étais comme "Oh, attends".
En tout état de cause, devoir se rappeler explicitement de verrouiller le mutex avant d'utiliser le vecteur est assez dangereux, car rien n'empêche mal utilisé accidentellement, et rien n'empêche les itérateurs de fuir. Un concurrent_vector code> est beaucoup plus sûr.
@Deadmg, est Concurrent_vector Code> Microsoft uniquement?
Il y a aussi un à TBB, qui est fondamentalement le même principe.
Si vous souhaitez utiliser un conteneur à utiliser à partir de nombreux threads, vous devez utiliser un conteneur explicitement conçu à cet effet. L'interface des conteneurs standard n'est pas conçue pour une mutation simultanée ni une sorte de concurrence, et vous ne pouvez pas simplement lancer un verrou au problème. P>
Vous avez besoin de quelque chose comme TBB ou PPL qui a Concurrent_vector Code>. P>
Vous devez probablement garder les opérations d'écriture avec des mutiles. Notez que même si vous verrouillez les opérations d'écriture, les itérateurs et les références peuvent être invalidés, il n'existe donc aucune solution totalement sûre. Vous ferez mieux de ne pas effectuer de modification des opérations de plus d'un fil.
Bonjour, une faute de segmentation est généralement causée par l'accès à la mémoire qui n'est pas réservée par votre processus. Pourrait-il être que vous utilisez quelque chose comme un pointeur qui n'est en réalité pas un pointeur? Sinon, consultez ceci: Stackoverflow.com/questions/1099513 / ...
@juanchopanza - pas seulement les opérations d'écriture, toutes les opérations b>. Chaque accès b> aux données partagés doit être protégé.
@Petebecker a accepté et certains accès (par exemple référence aux éléments du conteneur ou des itérateurs), vous ne pouvez pas vraiment protéger de toute façon ...