名前付きのSystem Vセマフォを使用して、OSXおよびLinux上のすべてのアプリケーション間でファイルをロックしています。どの定義でもAPIの中で最もきれいです。名前付きSystem Vセマフォを正しく破棄する
これはうまくいくようですが、誰もがそれを実行した後、セマフォを正しく破棄する方法がわかりません。
一般的なロジックは、このようなものです:
は作成:は
[1]スレッドやプロセスがftokにより、ファイルのために作成されたkey_t()で設定したセマフォを開こうとします。セットには2つのセマフォが含まれます。 [2]セマフォセットが存在しない場合、セマフォセットは666のパーミッションで作成されます。 [3] "ロック"(セマフォの1つ)が解放状態(値1)に設定されています。 [4]「参照カウント」(同じセット内の別のセマフォ)がインクリメントされます。
ロック/アンロック:
[5]は、スレッド1によって「ロック」セマフォの値をデクリメントロックする(元に戻すと)、それは既にゼロである場合、従って待っ。 [6]をロック解除するには、スレッドは1をインクリメントして、他の誰かがそれをロックできるようにします。
破棄:
[7] "参照カウント" セマフォは(IPC_NOWAITフラグ付き)デクリメントすることを試みています。 [8]その値は0にチェックされ、[9]であればセマフォセットは破棄されます。
(1つのスレッド内でロック再帰を作るために、スレッドローカルストレージに基づいた論理の層もあります。)
質問は次のとおりです。
- は、どのように私はステップを同期します[1]と[2]? (セマフォーセットが存在しない場合は星を数えている間に誰かによって作成されたため、作成も失敗します)
- [9]と[8]を同期させるにはどうすればよいですか?早期に私を殺さない?
- その他の競合条件はありますか?
PS:POSIXセマフォは、非常に良くAPIがありますが、私はここで説明したように、私はsem_inlink()の挙動を生き残ることができるとは思わない:(sem_openする
コール)を再作成または 再にsem_unlink()が呼び出された後に 新しいセマフォを参照すると、セマフォに接続します。 が呼び出されました。
だから私は...
私は致命的な欠陥については分かりません。セマフォの作成はアトミックです(私は願っていますか?)。次のプロセスは実際にそれを取得するか、最悪の場合は作成する呼び出しに失敗します(ループ内で再度取得する必要があります)。それから、プロセスの作成が完了するまで(1に設定)、他の人はすでに既存のsemを取得し、 "ロック"(-1で)しようとすると待機します。プロセスを作成するとコントロールが失われますが、それはすべてOKです。 – Eugene
(実際には、私の質問に答えるだけで、ループは欲しかったのです:)) – Eugene
semを永遠に保つのは、Linuxの最大値は通常128セットのような非常に小さいです。少数のファイルだけをロックする必要がありますが、私の単体テストはかなり早く到達します。これが、私が使用しないときに殺す主な理由です。 – Eugene