Ich habe ein einfaches .NET-Programm, das prüft, ob eine andere Instanz gestartet wurde:
%Vor%Meine Frage ist, was genau passiert mit dem Mutex, wenn Sie vergessen, es zu veröffentlichen, wenn das Programm endet? Ist es in einigen Windows-Systemsteuerung Komponenten sichtbar? Wo lebt es?
Es ist ein benannter Mutex, also ist er sichtbar und kann in anderen Prozessen geöffnet werden. Windows verwendet eine einfache Verweisanzahl auf dem Handle. Wenn Sie es nicht explizit disposieren (), schließt der Finalizer das Handle für Sie. Wenn Ihr Programm hart bombardiert und niemals den Finalizer ausführt, wird Windows es tun, wenn es die von Ihrem Programm verwendeten Ressourcen aufräumt.
Dadurch wird die Referenzzählung automatisch dekrementiert. Wenn dies auf Null zählt (keine anderen Prozesse haben ein Handle geöffnet), wird das Kernel-Objekt freigegeben.
Mit anderen Worten: Sie haben kein Problem, egal wie schlimm die Dinge ausgehen. Das tatsächliche mutierte Objekt befindet sich im Kernelspeicherpool. Sie können es mit dem WinObj-Tool von SysInternals sehen.
Von MSDN
Wenn ein Thread endet, während er a besitzt Mutex, wird der Mutex gesagt verlassen. Der Zustand des Mutex ist gesetzt auf signalisiert und das nächste warten Thread erhält Besitz. Wenn niemand besitzt der Mutex ist der Zustand des Mutex signalisiert. Ab Version 2.0 von das .NET Framework, ein AbandonedMutexException wird ausgelöst der nächste Thread, der den Mutex. Vor der Version 2.0 des .NET Framework war keine Ausnahme geworfen.
Vorsicht
Ein abgebrochener Mutex weist oft auf a hin schwerwiegender Fehler im Code. Wenn ein Thread beendet, ohne die Mutex, die Datenstrukturen geschützt durch den Mutex könnte nicht in a sein konsistenter Zustand Der nächste Thread zu Anfrage Besitz des Mutex kann Behandeln Sie diese Ausnahme und fahren Sie fort, wenn die Integrität der Datenstrukturen kann verifiziert werden.
Im Falle eines systemweiten Mutex, a abgebrochener Mutex könnte anzeigen, dass ein Anwendung wurde beendet abrupt (zum Beispiel durch Verwendung von Windows Task-Manager).
Mutexes sind Handles auf Betriebssystemebene. Sie werden geschlossen, wenn Ihr Prozess funktioniert (wenn Sie sie nicht früher schließen, also.)
Bearbeiten
Ok, ich habe das Beispiel und eindeutig falsch verstanden. Wenn Sie nur herausfinden möchten, ob eine andere Instanz existiert, würden Sie einen benannten Mutex (oder ein ähnliches Objekt) erstellen und einfach nach seiner Existenz suchen, ohne ihn zu sperren.
Der Aufruf von WaitOne
wird gesperrt, wobei die Eigentümerschaft übernommen wird, während ReleaseMutex
ihn löscht (solange keine zusätzlichen Aufrufe von WaitOne
erfolgen). Wenn Sie den Thread beenden, ohne den Mutex vollständig freizugeben, bleibt das Objekt in einem schlechten Zustand, wie im Text von Micah beschrieben.
Ich habe Ihre Frage so behandelt, als ob Sie den Handle schließen würden, bevor der Prozess abgeschlossen ist, was eine ganz andere Sache ist.
zusätzlich
Auf der Ebene SDK [API] [1] können Sie CreateMutex
mit der Erwartung aufrufen, dass ein Fehler auftritt, wenn ein Mutex desselben Namens bereits erstellt wurde. In .NET (zumindest in 4.0) gibt es einen [Konstruktor] [2], der ein createdNew
bool füllt.
[1]: Ссылка CreateMutex
[2]: Ссылка Mutex