3

Boostのshared_lockライブラリとunique_lockライブラリを使用して、リソースに基本的なリーダーライターロックを実装しようとしています。ただし、リソースにアクセスするスレッドの中には、単にクラッシュする可能性があるものがあります。ミューテックスを指定してミューテックスを監視し、どのプロセスがリソースをロックし、各プロセスがどのくらいの期間ロックされているかを追跡する別のプロセスを作成したいと思います。また、プロセスは、指定された期間を超えてロックを保持している場合、プロセスにロックを解放するように強制します。

ブーストロックはすべてスコープロックであり、スコープ外になると自動的にロックが解除されますが、サーバーがクラッシュした場合でも問題は解決しないため、SIGSEGVがプロセスに送信されて強制終了されます。強制終了されたプロセスは、デストラクタを呼び出さないため、保持されているリソースを解放しません。

考えられる解決策の1つは、ロックにタイマーを設定して、一定期間のロック後にプロセスが強制的にロックを解除するようにすることです。これはロックの概念に反しますが、この場合は機能します。これは、いずれかのプロセスがたとえば5分を超えてロックを保持している場合、プロセスが強制終了されたか、存在していると言っても安全であるためです。デッドロック状態。

この問題に取り組む方法についての提案は大歓迎です!


以前のスレッドは「重複の可能性がある」ために閉じられましたが、記載されている重複する質問は私の質問に答えません。

ブースト:ミューテックスのステータスを監視し、デッドロック時にリリースを強制する方法

4

2 に答える 2

0

@Arno: そもそもクラッシュしないように、ソフトウェアが非常に堅牢である必要があることに同意しません。フォールト トレランス システム (ファイブ ナインの可用性を考えてください) では、重要なプロセスが突然終了した場合に備えて、適切なチェックを行う必要があります。ライン上の何かpthread_mutexattr_*robust

所有者 pid を保存すると、ミューテックスの最後に使用されたタイムスタンプが回復に役立ちます。

于 2012-11-28T07:05:43.953 に答える
0

これが良いアイデアであるかどうかは別として、共有メモリを利用してタイムスタンプ、プロセス識別子、およびスレッド識別子を格納する独自のミューテックス実装を展開することができます。

スレッドがロックを取得する必要がある場合、共有メモリで空のスロットを見つけ、Windows の InterlockedCompareExchange などのアトミックなテストおよび設定操作を使用して、現在の値が空の値である場合にプロセス ID を設定する必要があります。セットが発生しない場合は、最初からやり直す必要があります。プロセス ID を設定した後、スレッドはスレッド ID のプロセスを繰り返し、タイムスタンプを使用して同じことを行う必要があります (ただし、設定するだけではなく、アトミックに行う必要があります)。

次に、スレッドは他のすべての満たされたスロットをチェックして、タイムスタンプが最も低いかどうかを判断する必要があります。そうでない場合は、タイムスタンプが最も低いスロットを記録し、空になるか、タイムスタンプが高くなるか、タイムアウトになるまでポーリングする必要があります。次に、スレッドがロックを取得した時点で最も古いタイムスタンプを持つスロットがスレッドに含まれるまで、リンスを繰り返します。

別のスロットがタイムアウトした場合、スレッドはタイムアウト ハンドラーをトリガーし (他のプロセスを強制終了するか、ロックされているスレッドで単に例外を発生させる可能性があります)、アトミック テストおよびセット操作を使用してスロットをクリアする必要があります。

ロックされたスレッドがロックを解除すると、アトミックなテストおよび設定操作を使用してスロットをクリアします。

更新: また、デッドロックの可能性を回避するために、最も低いタイムスタンプ間の関係を処理する必要があり、その処理は競合状態の作成を回避する必要があります。

于 2012-11-13T06:02:39.823 に答える