2009-06-25 7 views
0

Est-il presque toujours nécessaire d'avoir une synchronisation de threads (c.-à-d. Utilisation de mutex, sémaphores, sections critiques, etc.) lorsqu'il y a accès aux données croisées, même si cela n'est pas nécessaire analyse des besoins?Meilleures pratiques: synchronisation entre threads

+5

Si ce n'est pas nécessaire, il est pas nécessaire. Que demandez-vous exactement? – sth

+0

Si je devrais verrouiller les threads lors de l'accès aux données sur les threads, qu'ils soient obligatoires ou non? – stanigator

+2

Si nécessaire (pour éviter la corruption de données), faites-le. Si ce n'est pas obligatoire, ne le faites pas ... –

Répondre

5

Je vous ai toujours recommandé d'utiliser le schéma de synchronisation le plus simple et le plus simple jusqu'à ce que l'analyse montre que vous devriez faire autrement - cela signifie généralement quelques gros verrous contre de nombreux verrous à grain fin ou sans verrou.

Le problème est que déterminer si le code sans verrouillage est correct est beaucoup plus difficile que de déterminer si le code correspondant avec des verrous est correct. Cela crée un fardeau important pour les mainteneurs de votre code, et il y a de fortes chances qu'ils se trompent et introduisent des bogues. Même si vous savez que le verrou est sûr avec la façon dont votre code est actuellement utilisé, cela pourrait changer à l'avenir par des gens qui ne sont pas aussi conscients. Deuxièmement, dans de nombreux cas, la différence de performance entre le code avec verrous et le code sans verrouillage est négligeable - jusqu'à ce que vous sachiez qu'il y a un problème avec la contention de verrou, vous ne devriez pas envisager de verrouiller. Même s'il y a des problèmes de contention, lock-free n'est pas forcément la meilleure solution.

+0

Merci pour votre explication. Je suppose que l'utilisation d'un verrou serait la meilleure pratique pour les futures raisons d'utilisabilité du code source. – stanigator

2

Même si vous n'avez pas besoin d'un mutex, d'un sémaphore, d'une section critique, etc. pour leur sémantique de verrouillage normale, vous aurez peut-être besoin d'un memory barrier. Les premières constructions impliquent généralement une barrière de mémoire, c'est pourquoi les supprimer peut changer le programme. En outre, ces problèmes peuvent être extrêmement difficiles à déboguer, car une planification différente des threads impliqués peut faire disparaître le problème et apparaître. Dans le cas le plus simple, cela signifie que le simple fait d'exécuter un programme complètement distinct change le comportement de votre part.

0

L'autre modèle qui a du sens s'appelle share-nothing. erlang et scala sont probablement les principaux représentants de ce modèle avec des processus erlang et des acteurs de scala. L'idée est que vous envoyez des messages à d'autres threads, où les messages sont des données dont aucune référence n'est conservée par l'expéditeur. En pratique, il y a une petite quantité de verrouillage nécessaire pour les files d'attente d'envoi/réception, mais le reste du code peut être verrouillé sans souci.

De tels modèles peuvent être implémentés en C++ et dans d'autres langages.

http://www.scala-lang.org/node/242 http://lambda-the-ultimate.org/node/1742 http://docs.python.org/library/multiprocessing.html#module-multiprocessing