Nach einigen Recherchen habe ich herausgefunden, dass System-V-Semaphore ein Flag namens SEM_UNDO haben, das den Sperrzustand rückgängig machen kann, wenn das Programm fehlschlägt, aber das funktioniert nicht garantiert.
SEM_UNDO würde das Semaphor entsperren, wenn der Prozess abstürzt. Wenn Prozesse aufgrund einer Beschädigung des gemeinsamen Speichers abgestürzt sind, können Semaphoren nichts für Sie tun. Das Betriebssystem kann den Zustand des gemeinsam genutzten Speichers nicht rückgängig machen.
Wenn Sie in der Lage sein müssen, den Status des gemeinsam genutzten Speichers zurückzusetzen, müssen Sie etwas Eigenes implementieren. Ich habe mindestens zwei Modelle gesehen, die sich damit befassen.
Das erste Modell vor dem Ändern von irgendetwas im gemeinsamen Speicher war das Erstellen einer Momentaufnahme der Struktur und das Speichern in einer Liste im gemeinsamen Speicher. Wenn ein anderer Prozess die Sperre erhalten konnte und die Liste nicht leer war, machte er alles rückgängig, was der abgestürzte Prozess möglicherweise geändert hatte.
Das zweite Modell besteht darin, Kopien der shm-Strukturen im lokalen Speicher zu erstellen und die Sperre für die gesamte Transaktion gesperrt zu halten. Wenn die Transaktion festgeschrieben wird, kopieren Sie einfach die Strukturen aus dem lokalen Speicher in den gemeinsam genutzten Speicher, bevor Sie die Sperre freigeben. Die Wahrscheinlichkeit, dass die App beim Kopieren abstürzt, ist geringer und der Eingriff durch externe Signale kann mit sigprocmask()
blockiert werden . (Das Sperren in dem Fall sollte besser gut über die Daten verteilt werden. Ich habe z. B. Tests mit einem Satz von 1000 Sperren für 10 Millionen Datensätze in shm gesehen, auf die von 4 gleichzeitigen Prozessen zugegriffen wird.)
Es gibt nur wenige Dinge, die garantiert bereinigt werden, wenn ein Programm fehlschlägt. Das einzige, was mir hier in den Sinn kommt, ist die Anzahl der Links. Ein offener Dateideskriptor erhöht die Linkanzahl des zugrunde liegenden Inodes und ein entsprechendes Schließen verringert sie, einschließlich eines erzwungenen Schließens, wenn das Programm fehlschlägt.
Ihre Prozesse könnten also alle eine gemeinsame Datei öffnen (erinnern Sie sich nicht, ob es für gemeinsam genutzte Speichersegmente funktioniert) und Sie könnten eine Art Alarm auslösen, wenn die Anzahl abnimmt, wo dies nicht der Fall sein sollte. Anstatt einfach zu warten, könnten Ihre Prozesse z. B. ein zeitgesteuertes Warten (z. B. für eine Sekunde) in einer Schleife durchführen und die Anzahl der Links abfragen, um benachrichtigt zu werden, wenn etwas schief geht.