私はAIXでコーディングしていますが、理想的には一般的なnixソリューションposix準拠のものを探しています。 C++ 11以降では何も使用できません。posix:プロセス間ロックが放棄されました、よりよい方法はありますか?
私は、関連する多くのプロセスから多くのスレッドと共有メモリを持っています。共有メモリ内のデータは自己一貫性を保たなければならないので、誰もが交代するようにロックが必要です。
ロックでクラッシュするプロセスは問題なので、放棄されたロックを検出し、データを修正(別名リセット)して移動する必要があります。ツイスト:一定期間固定を待ってロックが放棄されたと判断することは実行可能な解決策ではありません。
グローバル・ミューテックス(共有メモリに存在するか名前が付けられている)は、解決策ではないようです。放棄(タイミングを除く)の検出メカニズムはなく、未定義の振る舞いを危険にさらすことなくmutexを削除したり改変することはできません。
私はlockf()とビジーフラグを選択しました。ファイルロックを取得し、共有メモリにフラグを設定し、処理し、フラグを解除し、ロックを解除します。ロックが所有されているクラッシュ時には、ロックは自動的に解除され、次にそれを取得する人は、ビジーフラグがまだ設定されているのを見ることができ、混乱を取り除かなければならないことがわかります。
これは機能しません。これは、lockf()は他のプロセスからのスレッドを保持しますが、独自のプロセス内の他のスレッドには特別なセマンティクスがあるためです。それはチェックされていないものを通過させます。
最後に、私はローカル(スレッド)ミューテックスとファイルロックという2つのステップの解決策を考え出しました。まず、ローカルミューテックスを取得します。今度は、このプロセスでlockf()という次のステップを実行する唯一のスレッドです。 lockf()は唯一のプロセスであることを保証します。したがって、ビジーフラグを設定して作業を行うことができます。ロックを解除するには、逆順に進みます。ビジーフラグをクリアし、ファイルロックを解除し、ミューテックスロックを解除します。クラッシュ時には、ローカルmutexは処理が終了すると消滅しますので、無害です。
正常に動作します。私はそれが嫌いです。このようにネストされた2つのロックを使用すると、私は高価なものになります。 (私の次のコードレビューは興味深い)。私はもっと良い解決策を見逃したような気がします。それは何ですか?
編集:@Matt私はおそらく明確ではありませんでした。ビジーフラグはロック機構の一部ではありません。何らかのプロセスがロックを正常に取得したことを示すためにそこにあります。ロックを取得した後、ビジーフラグがすでに設定されていると、ロックを取得してクラッシュした他のプロセスが、書き込み中の共有メモリを不完全な状態にしていることを意味します。その場合、ロックを所有しているスレッドは共有メモリを使用可能な状態に再初期化するジョブを取得します。私はおそらくそれを "memoryBeingModified"フラグと呼んでいたはずです。
"tryLock"のバリエーションは許されません。このアプリケーションでは、ポーリングは絶対に問題になりません。共有メモリを変更する必要のあるスレッドは、ロックをブロックすることはできません(長い間保持されることはありません)。ロックが利用可能になるとすぐにそのスレッドを処理する必要があります。彼らは最小限の遅延を経験しなければならない。
私はおそらく明確ではありませんでした。ビジーフラグはロック機構の一部ではありません。何らかのプロセスがロックを正常に取得したことを示すためにそこにあります。ロックを取得した後でビジーフラグがすでに設定されていると、ロックを取得してクラッシュした他のプロセスが、書き込み中の共有メモリを不完全な状態にしていることを意味します。その場合、ロックを所有しているスレッドは共有メモリを使用可能な状態に再初期化するジョブを取得します。 – user15001
ああ、まあ、問題ありません。私はtrylockをlock()に変更しました。これは簡単です。 –