名前付き System V セマフォを使用して、OSX および Linux 上のすべてのアプリでファイルをロックしています。どの定義から見ても、最も美しい API ではありません。
動作しているように見えますが、全員がセマフォを使い終わった後、セマフォを適切に破棄する方法がわかりません。
一般的なロジックは次のようになります。
作成:
[1] スレッドまたはプロセスは、ftok() によってファイル用に作成された key_t で設定されたセマフォを開こうとします。セットには 2 つのセマフォが含まれています。[2] セマフォ セットが存在しない場合は、666 パーミッションで作成されます。[3] 「ロック」(セマフォの 1 つ) が解放状態 (値 1) に設定されます。[4] 「参照カウント」(同じセット内の別のセマフォ) がインクリメントされます。
ロック/ロック解除:
[5] をロックするには、スレッドは「ロック」セマフォの値を 1 減らします (元に戻す機能を使用)。したがって、値が既にゼロである場合は待機します。[6] のロックを解除するために、スレッドはそれを 1 つ増やし、他の誰かがロックできるようにします。
破壊:
[7] 「参照カウント」セマフォをデクリメントしようとしています (IPC_NOWAIT フラグを使用)。[8] その値が 0 であることを確認し、[9] セマフォ セットが破棄されます。
(1 つのスレッド内でロックを再帰的にするための、スレッド ローカル ストレージに基づくロジックのレイヤーもあります。)
質問は次のとおりです。
- 手順 [1] と [2] を同期するにはどうすればよいですか? (セマフォ セットが存在しない場合、星を数えている間に他の誰かによって作成されたため、作成も失敗します)
- ステップ [4] を [8] と同期させて、[9] で早死にさせないようにするにはどうすればよいですか?
- 他の競合条件はありますか?
PS: POSIX セマフォにはより優れた API がありますが、ここで説明されているように sem_inlink() の動作を乗り切ることはできないと思います。
セマフォを再作成または再接続するための sem_open() の呼び出しは、 sem_unlink() が呼び出された後に新しいセマフォを参照します。
だから私は彼らを解放する方法がありません...