2011-01-07 8 views
4

バイト配列Private Data as Byte()があるとします。この配列はクラス内ではプライベートです。このクラスは、Dataに読み書きするための公開関数を提供します。WriteLock on Write?読む?または両方?

このクラスには複数のスレッドがアクセスできるため、このスレッドからの読み取りと書き込みは同時に行われません。

今のところ、問題を避けるためにSyncLockを使用しています。書き込み機能にSyncLock Dataを入れることはできますか、それとも読み取り機能にする必要がありますか?または両方?

私は、特定のコード例を念頭に置いていません。私は、書き込み関数のSyncLockが書き込みを最初にそれに排他的にアクセスさせるようにすると、読み取りと書き込みの両方の機能をロックすることに何らかの利益があるかどうか不思議です。

答えて

3

バイト配列の読み込みをロックする主な理由は、「ファントム読み取り」やその他の繰り返し不可能な読み取りを避けることです。ライターが途中で配列を更新している場合、リーダーは古い値いくつかの新しい値、古い値、そして新しい値を読み込みます。

たとえば、[1,2,3,4,5,6]を含む配列と、SyncLockを受け取り、配列全体をループして各要素に1を加える書き込みスレッドの場合、 SyncLockでは[2、3、4、4、5、6]のような奇妙なメッセージが表示されることがあります。実際にはSyncLockのスレッドのみが安全性を受け取ります。

+0

はい、これは私が避けたいものです。しかし、バイト配列に書き込むときに 'SyncLock'を使用している場合は、この問題はありませんか? – Brad

+1

ロックに参加しているスレッドのみが保護されます。ロックしていないスレッドは半更新状態を見ることができます。 –

+0

はい、できます。書き込み操作だけをロックし、読み取り操作をロックしない場合は、無効なデータを読み取っている可能性があります。それがこの投稿が言っていることです。 –

4

SyncLockを使用する代わりに、ReaderWriterLockSlim(または.NET 4に属していない場合はReaderWriterLock)の使用を検討する必要があります。

これは、単一のライターが複数のリーダーを許可することを意図しています。これは、典型的には、記述しているような状況に最適です。

これ以外の場合は、SyncLockを使用できますが、読み取りと書き込みの両方の操作をロックする必要があります。両方にロックをかけなければ、ライターがまだ書き込み中のときにリーダーがデータを読み取る可能性があります。これにより、ハーフセットのデータを読み取ることになります。

+0

私はReaderWriterLockSlimを見ていきます。 – Brad

関連する問題