web-dev-qa-db-ja.com

オブジェクトから読み取るときにオブジェクトをロックする必要がありますか?

複数のスレッドで共有されるオブジェクトがあるプログラムを書いています。

  • A)複数の書き込みスレッドがオブジェクトに書き込みます(すべて同じ関数を実行しています)
  • B)5秒ごとにオブジェクトにアクセスする読み取りスレッド
  • C)ユーザーの要求があるオブジェクトにアクセスする読み取りスレッド

複数のスレッドが同時にオブジェクトに書き込むことは望ましくないため、オブジェクトに書き込むときは明らかにオブジェクトをロックする必要があります。

私の質問は次のとおりです。

  1. オブジェクトから読み取るときにもオブジェクトをロックする必要がありますか?
  2. 書くときにオブジェクトをロックするだけなら、クリティカルセクションで十分だと思うのは正しいですか。しかし、読み取りまたは書き込み時にオブジェクトをロックする場合、ミューテックスが必要ですか?

Microsoft Officeでは、Wordの2つのインスタンスが読み取り/書き込みアクセスモードでドキュメントにアクセスすることはできないため、この質問をしています。ただし、ドキュメントを読み取り/書き込みモードで開いているときに、Wordの別のインスタンスを開いて、読み取り専用モードでドキュメントにアクセスすることができます。同じロジックがスレッドに適用されますか?

25
Andy

Ofirがすでに書いたように、他のスレッドが変更しているオブジェクトからデータを読み取ろうとすると、一貫性のない状態でデータを取得する可能性があります。

ただし、オブジェクトが変更されていないことが確実な場合は、もちろん複数のスレッドから読み取ることができます。一般的に、あなたが尋ねている質問は多かれ少なかれ読者-作家の問題です http://en.wikipedia.org/wiki/Readers-writers_problem を参照してください

最後に、クリティカルセクションは抽象的な用語であり、ミューテックスまたはモニターを使用して実装できます。 JavaまたはC#(同期、ロック)のクリティカルセクションのシンタックスシュガーは、内部でモニターを使用します。

18

それ以外の場合(操作がアトミックでない限り)、中間状態を読み取っている可能性があるため、これが必要です。

(ビット)より複雑な種類のロックを必要とする複数のリーダーを同時に許可したい場合があります。

5
Ofir

オブジェクトから読み取るときにもオブジェクトをロックする必要がありますか?

他の何かが同時にそれに書き込むことができれば-はい。別の読み取りのみが発生する可能性がある場合-いいえ。あなたの状況では、私は言うでしょう-はい。

書くときにオブジェクトをロックするだけなら、クリティカルセクションで十分だと思うのは正しいですか。しかし、読み取りまたは書き込み時にオブジェクトをロックする場合、ミューテックスが必要ですか?

いいえ、両方にクリティカルセクションを使用できます。他の条件は同じです。ミューテックスはセクションに機能を追加しました(たとえば、名前付きミューテックスは複数のプロセスから使用できます)が、ここではそのような機能は必要ないと思います。

4
anon
  1. あなたがそれをどのように使用し、読むかに依存します。読み取りがアトミックであり(つまり、書き込みによって中断されない)、読み取りスレッドが書き込みスレッドとの依存関係を持たない場合は、読み取りロックをスキップできる可能性があります。ただし、「読み取り」操作に時間がかかり、オブジェクトの相互作用が重い場合は、読み取り用にロックする必要があります。

  2. 読み取りにそれほど時間がかからない場合(つまり、書き込みスレッドの遅延が長すぎない場合)、クリティカルセクションで十分です。

3
Francis

ロックは、2つのプロセスが同じデータベーステーブル要素を変更できる場合にのみ必要です。あなたがデータを読みたいとき、それは常に安全です。一貫性のあるデータベースのデータを読み取ります。データを変更するプロセスには一貫性のあるシャドウバージョンがあり、保存すると現在のデータが上書きされます。ただし、データベース要素からの重要な値に依存する読み取りプロセスを実行している場合は、それらの値が変更される可能性があることを示すロックを探す必要があります。そのため、ロックが解除されるまで読み取りが遅れます。

0
guido bouman