2009-03-17 6 views
3

J'ai plusieurs threads qui acquièrent des Mutex puis se terminent.Recherché: Synchro-processus qui ne souffre pas de l'exception AbandonedMutexException

Les mutex sont stockés dans un référentiel principal et sont libérés correctement lorsque le programme existe. Cependant, quand le thread qui a alloué un Mutex existe, le mutex est libéré automatiquement, et ensuite acquiert AbandonedMutexException (également selon the documentation).

Comment puis-je éviter cette exception et continuer à utiliser un Mutex même après l'achèvement du thread d'allocation? Y a-t-il une autre construction de synchronisation plus appropriée dans .Net qui n'a pas cette limitation.

Remarque - Je recherche un mécanisme de synchronisation entre processus avec une sémantique similaire à Mutex.

Répondre

1

On dirait que EventWaitHandle fait ce que je veux. Il a un constructeur qui prend un nom, donc c'est parfait pour la synchronisation entre processus, et il n'a pas ce problème.

6

Réponse à la question

il existe AFAIK pas de classe Mutex. L'exception AbandonedMutexException est assez ennuyeuse mais représente une situation réelle qui peut survenir sans solution automatique. Lorsque vous avez une communication croisée, ou même une communication croisée, vous devez tenir compte du fait que l'une des entités participantes peut être inattendue et interrompue brusquement pour un certain nombre de raisons. Mutex existe pour protéger les ressources, si un thread est abandonné alors qu'il contient un Mutex, il n'y a aucun moyen pour l'OS de garantir qu'il a laissé des données de manière cohérente. Ceci est très important car cela signifie que l'abandon du thread pourrait avoir invalidé certains invariants dépendants d'autres threads. L'exception AbandonedMutexException est une manière de dire de manière proactive que "de mauvaises choses sont arrivées et vous êtes maintenant dans un état indéterminé". Il n'y a vraiment pas d'autres recettes pour le système d'exploitation ici.

Réponse à votre réponse

EventWaitHandle est différent que Mutex et sert à des fins différentes. Mutex est utilisé pour protéger une ressource particulière à la manière d'une instruction de verrouillage. Quand un thread particulier acquiert un mutex, on dit qu'il possède le mutex. Il ne peut y avoir qu'un seul propriétaire à la fois. Par conséquent, si tous les threads concernés acceptent de toucher uniquement une ressource lorsqu'ils sont propriétaires du Mutex, vous pouvez accéder en toute sécurité à une ressource sur le thread.

EventWaitHandle peut être visualisé, dans une certaine mesure, comme un événement thread-safe. Il a le concept de signaled et unsignaled et n'importe quel nombre de threads peut l'attendre pour atteindre un état signalé. Quand il est signalé l'un des fils d'attente sera réveillé et commencera le traitement.

Vous pouvez utiliser un EventWaitHandle pour implémenter une forme de sécurité de thread. Au lieu que la propriété du verrou soit la clé pour accéder à la ressource, être signalé à partir de l'événement est la clé pour accéder à la ressource. Cependant, le diable est une fois de plus dans les détails.

  1. Qui est responsable de la signalisation de l'événement? Avec un mutex, chaque thread hurle essentiellement "moi moi" et l'OS choisit un thread pour gagner.Avec EventWaitHandle, vous serez responsable de décider quand le prochain thread arrivera.
  2. Que se passe-t-il lorsque quelqu'un tue un processus via taskmgr? Que se passe-t-il si le processus tué a un thread qui répond actuellement à un événement sur EventWaitHandle?
  3. 2 mais que se passe-t-il lorsque l'élément qui parvient à signaler la poignée d'attente suivante est supprimé? Vous devez en tenir compte pour éviter les interblocages.

+0

Il s'est avéré que pour mon but, un simple événement était tout aussi bon (mieux parce qu'il n'est pas devenu abandonné). Merci pour la réponse détaillée. Je n'ai pas à décider "qui gagne" - le système d'exploitation décide toujours lequel des deux threads gagne un AutoResetEvent.Wait(). – ripper234

+0

@ ripper234 mais vous le faites bien. Vous répondez en appelant la méthode Set et en décidant ainsi quand l'OS décide qui gagne. – JaredPar

+2

Tout comme je suis responsable de la libération du mutex. Pour mon but, je ne voulais surtout pas que l'OS décide pour moi que le mutex devrait être libéré. – ripper234

0

Rien ne vous empêche d'utiliser le Mutex après avoir reçu un AbandonedMutexException. De l'doc:

Le thread suivant pour demander la propriété du mutex peut gérer cette exception et procéder, à condition que l'intégrité des données structures peut être vérifiée.

Bien sûr, cela suppose que vous savez ce que vous (et vos fils) faites alors qu'ils plantent, et cela signifie essentiellement que le thread demandeur pourrait tout aussi bien libérer le mutex avant de quitter. Donc, à la fin, votre propre solution d'utilisation EvenWaitHandle est une meilleure solution que le mutex.