Takže při nějakém průzkumu jsem zjistil, že semafory System V mají příznak nazvaný SEM_UNDO, který může vrátit stav uzamčení, když program selže, ale není zaručeno, že bude fungovat.
SEM_UNDO odemkne semafor, pokud proces selže. Pokud procesy havarovaly kvůli poškození sdílené paměti, semafory pro vás nemohou nic udělat. OS nemůže vrátit stav sdílené paměti.
Pokud potřebujete být schopni vrátit stav sdílené paměti zpět, musíte něco implementovat sami. Viděl jsem nejméně dva modely, které se tím zabývají.
Prvním modelem před úpravou čehokoli ve sdílené paměti bylo pořízení snímku struktury a uložení do seznamu ve sdílené paměti. Pokud jakýkoli jiný proces dokázal získat zámek a seznam nebyl prázdný, vracel vše, co mohl zhroucený proces změnit.
Druhým modelem je vytvořit kopie struktur shm v místní paměti a ponechat zámek uzamčený pro celou transakci. Když je transakce potvrzena, před uvolněním zámku jednoduše zkopírujte struktury z místní paměti do sdílené paměti. Pravděpodobnost, že aplikace během kopírování selže, je nižší a zásah externích signálů lze zablokovat pomocí sigprocmask()
. (Zamykání v pouzdru je lepší dobře rozdělit na data. Např. viděl jsem testy se sadou 1000 zámků pro 10Mln záznamů v shm, ke kterým přistupují 4 souběžné procesy.)
Existuje jen málo věcí, které se zaručeně vyčistí, když program selže. Jediné, co mě tady napadá, jsou počty odkazů. Otevřený deskriptor souboru zvyšuje počet odkazů základního inodu a odpovídající zavření jej snižuje, včetně nuceného zavření, když program selže.
Takže všechny vaše procesy by mohly otevřít společný soubor (nepamatuji si, jestli to funguje pro segmenty sdílené paměti) a mohli byste spustit nějaký alarm, pokud se počet sníží, kde by neměl. Např. místo prostého čekání mohou vaše procesy provést timedwait (např. na sekundu) ve smyčce a dotazovat se na počet odkazů, aby byly upozorněny, když se něco pokazí.