そこで、調査を行った結果、System V セマフォには、プログラムが失敗したときにロック状態を元に戻すことができる SEM_UNDO というフラグがあることがわかりましたが、それが機能する保証はありません。
SEM_UNDO は、プロセスがクラッシュした場合にセマフォのロックを解除します。共有メモリの破損が原因でプロセスがクラッシュした場合、セマフォができることは何もありません。 OS は共有メモリの状態を取り消すことができません。
共有メモリの状態をロールバックできるようにする必要がある場合は、自分で何かを実装する必要があります。これに対処するモデルを少なくとも 2 つ見たことがあります。
共有メモリ内の何かを変更する前の最初のモデルは、構造のスナップショットを取り、共有メモリ内のリストに保存していました。他のプロセスがロックを取得でき、リストが空でない場合、クラッシュしたプロセスが変更した可能性のあるものはすべて元に戻していました。
2 番目のモデルは、ローカル メモリに shm 構造のコピーを作成し、トランザクション全体でロックをロックしたままにすることです。トランザクションがコミットされている場合、ロックを解除する前に、構造をローカル メモリから共有メモリにコピーするだけです。コピー中にアプリがクラッシュする確率が低くなり、sigprocmask()
を使用して外部信号による介入をブロックできます . (この場合のロックは、データを適切に分割することをお勧めします。たとえば、4 つの同時プロセスによってアクセスされる shm の 10Mln レコードに対して 1000 個のロックのセットを使用したテストを見てきました。)
プログラムが失敗したときにクリーンアップされることが保証されているものはほとんどありません。ここで頭に浮かぶのはリンク数だけです。ファイル記述子を開くと、基礎となる inode のリンク数が増加し、それに対応して閉じると、プログラムが失敗したときの強制終了を含め、それが減少します。
したがって、プロセスはすべて共通のファイルを開くことができ (共有メモリ セグメントで機能するかどうかは覚えていません)、カウントが減少した場合に何らかのアラームをトリガーすることができます。たとえば、単純な待機を行う代わりに、プロセスがループ内で timedwait (たとえば、1 秒間) を実行し、リンク カウントをポーリングして、何か問題が発生したときに警告を発することができます。