1

Web アプリケーションには完全な -s がいくつかlockありますが、それらを読み取り/書き込みロックに置き換えると、パフォーマンスが向上する可能性があります。RW ロックの追加のオーバーヘッドがあっても、コードはより並列になります。残念ながら、ReaderWriterLockSlim特定のハードウェアでデッドロックを引き起こす可能性があるかなり大きな同期バグのように見えるため、使用できません。この記事では、この問題について詳しく説明します。

上記の問題は .NET Framework 4.0.30319.33440 で修正されているようですが、すべての Windows サーバー バージョンでこの修正が適用されるわけではありません。Windows 8.1 および Windows Server 2012 R2 には修正プログラムがあります。Windows Server 2012 (R2 ではない) および Windows Server 2008 R2 には、最新のパッチを適用した後でもまだバグがあります。Microsoft は、すべてのプラットフォームでこの問題を修正する予定はないようです。

私たちのさまざまなサーバー環境はさまざまなバージョンの Windows Server を使用しており、一部のサーバーには修正プログラムがあり、一部のサーバーには修正されていないことが確認されています。これは、一部のサーバーではアプリケーションがランダムにデッドロックする可能性があるため、これらすべてのlockステートメントをリーダー/ライター ロックに安全に変更できないことを意味します。

ReaderWriterLockSlim別の方法として、 System.Core のコードを逆コンパイルしMyRWLock、1 つの (既知の) バグのある関数がExitMyLock修正された新しいクラス (のようなもの) を作成して再実装することを検討しています。その他のコードはすべてオリジナルと同じReaderWriterLockSlimです。

これには、すべての属性を削除し、 の__DynamicallyInvokable内部にある 2 つまたは 3 つのクラス/構造を追加する必要がありますSystem.Core。私はこれをすべて行い、新しいロッククラスをエラーなしでコンパイルしました。

私の質問は、この新しいクラスが元のクラスのように機能しない理由を考えられる人はReaderWriterLockSlimいますか? スレッド化に関しては、自分はかなり上手だと思いますが、専門家ではありません。MyRWLockコードを変更していないので (一部の型名を and 属性の代わりにnew を指すように修正する以外はReaderWriterLockSlim)、これでうまくいくと思います。しかし、デバッグが難しいさまざまな興味深い方法でこれを壊す可能性のある何かを忘れていたのではないかと思います。

あるいは、私の(およびリンクされた記事の)理解は間違っていますか?そもそもこの問題は修正する必要がないのでしょうか? その記事の著者は非常に詳細な分析を行ったようで、私には正しいように見えますが、Microsoft は特定の Windows Server バージョンに変更を適用しませんでした。

これについての考えは大歓迎です。

編集

完全なロックのコンテキストをさらに追加するために、これがその目的です。リモートサービスが作業を実行するときに読み取り/書き込みを行うサービスがあります。書き込みより読み取りの方が多い。読み取りには 1 回のネットワーク ラウンドトリップが含まれ、書き込みにはリモート サービスへの 3 回のネットワーク ラウンドトリップが含まれます。書き込みが発生すると、読み取りが発生しない場合があります (書き込みは、実際には読み取り -> 削除 -> 追加です)。現在、lockこれらすべての操作で完全な -s を使用していますが、これは、書き込みがなくても、読み取りを試みるすべてのスレッドが現在の読み取りが完了するまでキューに入れなければならないことを意味します。これにはRWロックが理想的だと思います。

4

1 に答える 1

1

記事は正確ですか?知らない。彼らは少なくとも、彼らが主張する問題に対処する .NET の更新を指摘しているので、存在することが示唆されます。一方で、それがあなたに当てはまるかどうかについてはまだ疑問があります。とにかく、デスクトップ x86 マシンはすべてのメモリ アクセスに対して volatile セマンティクスを備えているため、説明されている唯一のバグが明示的な volatile 操作の欠如である場合、それはそこにあるハードウェアの大部分では問題になりません。

大規模なサーバー ハードウェアでは、アーキテクチャが異なり、セマンティクスが異なる可能性があり、明示的に揮発性の操作が必要になります。それはあなたが研究したいものかもしれません。

もちろん、ハードウェア アーキテクチャに関係なく、「揮発性」は .NET コンパイラにとっても意味があります。この記事で引用されているコードは、コンパイラの最適化によって影響を受けるようには見えませんが、私はその分野の専門家ではないので、確かなことは言えません。

このバグが発生するのを実際に目撃したことがないという質問から私はそれを取ります. 現時点では、それは純粋に仮説上の懸念です。

元のソースを出発点として使用しても、このタイプのクラスを再実装しようとするのは慎重です。

私の最初の選択は、あなたが参照した記事で説明されているバグが修正されている十分に新しい .NET バージョンにアップグレードしたことを確認することです。

2 番目の選択肢は、ReaderWriterLockSlim の代わりにプレーンな ReaderWriterLock クラスを使用することです。

3 番目の選択肢は、ネイティブの Win32 "スリム リーダー/ライター ロック" 構造を使用することです (つまり、p/invoke または C++/CLI を使用)。

これらのオプションのいずれも実行可能であることが証明されない場合にのみ、私は自分のリーダー/ライター ロックを実装するために苦労します。 volatile フラグを 1 つ使用することはできますが、それ以外の場合は、従来のMonitor- ベースのコードに固執します)。

于 2014-10-24T00:41:15.980 に答える