Lesedauer 3 Minuten

Ein Mutex, kurz für “Mutual Exclusion” (zu Deutsch: “gegenseitiger Ausschluss”), ist ein Mechanismus in der Informatik, der dazu dient, den gleichzeitigen Zugriff mehrerer Prozesse auf gemeinsam genutzte Ressourcen zu kontrollieren. Das Hauptziel eines Mutex besteht darin, sicherzustellen, dass nur 1 Prozess auf die geschützte Ressource zugreifen kann, um inkonsistente Daten oder unerwünschte Wettlaufbedingungen, sogenannte Race-Conditions zu verhindern.

Der Mutex-Mechanismus im Detail

Ein Mutex arbeitet in der Regel nach dem Prinzip “Lock” und “Unlock”. Wenn ein Prozess eine geschützte Ressource verwenden möchte, versucht er, das Mutex zu sperren (Lock). Wenn das Mutex bereits von einem anderen Prozess gesperrt ist, wird der anfragende Prozess blockiert und muss warten, bis das Mutex freigegeben wird. Wenn der Prozess fertig ist, gibt er das Mutex frei (Unlock), damit andere Prozesse darauf zugreifen können.

python mutex pywin32 mechanismus

Mutexe sind in Multithreading-Anwendungen und parallelen Programmen von entscheidender Bedeutung, um Datenkonsistenz und die Vermeidung von Race-Conditions sicherzustellen. Es gibt verschiedene Implementierungen von Mutexen, darunter softwarebasierte Mutexe und hardwareunterstützte Mutexe, je nach den Anforderungen und der Architektur des Systems.

Python und das Problem mit PyWin32

Arbeitet man mit Python unter Windows, benötigt man das PyWin32-Modul um dann über PyWin32Event auf die Mutex-Funktion des Betriebsystems zuzugreifen. Leider benötigt PyWin32 je nach Version spezifische C++ Runtime Packages, eine spezielle Pfad-Konfiguration und je nach Anwendung Admin-Rechte. Arbeitet man mit einem embedded Python-Interpreter, machen es diese Voraussetzungen oft unmöglich PyWin32 sauber zu installieren, bzw. die Installation portabel zu halten.

Die Lösung: Mutex per CTypes

Die folgende Python-Klasse implementiert Mutex über direkte Windows Kernel-Aufrufe via CTypes, komplett ohne PyWin32 und ohne weitere Abhängigkeiten:

Zum Testen kann man das Script in 2 Terminals starten:

  • Prozess 1 läuft durch, während Prozess 2 blockiert wird.
  • Bricht man Prozess 1 per CTRL-C ab, beginnt Prozess 2 weiter zu laufen.

python mutex ohne pywin32

Die Funktionsweise ist simpel:

  • Über .create() versucht der Prozess das Mutex zu erzeugen.
  • So lange .create() False zurück gibt, muss der Prozess warten.
  • Liefert .create() True, besitzt der Prozess das Mutex und darf seinen Code ausführen.
  • Am Ende wird per .release() das Mutex für andere Prozesse freigegeben.

Bei unserem Test wird .release() über den CTRL-C Interrupthandler der Klasse getriggert.

 

 

Hat Dir der Beitrag gefallen?

Wenn Du Fragen oder Anmerkungen zu diesem Beitrag hast, dann starte einen Kommentar. DANKE für Dein Feedback!