4

一度に 1 つのスレッドのみがロックされたデータにアクセスすることをロックが保証する場合、何がロック機能へのアクセスを制御するのでしょうか?

ローカル変数が別のスレッドによって予期せず変更されないように、各関数の先頭にboost::mutex::scoped_lockを配置する必要があると思いましたが、正しいですか? 2 つのスレッドが非常に近い時間にロックを取得しようとするとどうなりますか? 内部で使用されるロックのローカル変数は、他のスレッドによって破損されませんか?

私の質問はブースト固有のものではありませんが、別のものを推奨しない限り、おそらくそれを使用します。

4

4 に答える 4

10

共有データへの排他的アクセスのみが必要です。それらが静的またはヒープ上にない限り、関数内のローカル変数はスレッドごとに異なるインスタンスを持ち、心配する必要はありません。ただし、共有データ(たとえば、ポインターを介してアクセスされるもの)を最初にロックする必要があります。

ロックがどのように機能するかについては、競合状態を防ぐように注意深く設計されており、多くの場合、原子性を保証するためにハードウェアレベルのサポートがあります。IE、アトミックであることが保証されているいくつかの機械語構造があります。セマフォ(およびミューテックス)は、これらを介して実装できます。

于 2009-01-17T05:31:58.037 に答える
10

そうです、ロックを実装するときは、2つのプロセスが同時にロックを取得しないことを保証する何らかの方法が必要です。これを行うには、アトミック命令を使用する必要があります。これは、中断することなく完了することが保証されています。そのような命令の1つは、テストアンドセットです。これは、ブール変数の状態を取得し、それをtrueに設定して、以前に取得した状態を返す操作です。

これにより、ロックを取得できるかどうかを継続的にテストするコードを記述できます。xがスレッド間の共有変数であると仮定します。

while(testandset(x));
// ...
// critical section
// this code can only be executed by once thread at a time
// ...
x = 0; // set x to 0, allow another process into critical section

他のスレッドは、クリティカルセクションに入るまでロックを継続的にテストするため、これは相互排除を保証する非常に非効率的な方法です。ただし、この単純な概念を使用すると、はるかに効率的なセマフォなどのより複雑な制御構造を構築できます(プロセスがループしていないため、スリープしているため)

于 2009-01-17T05:32:50.000 に答える
4

最も簡単な説明は、その下にあるロックは、アトミックであることが保証され、スレッド間で衝突しないハードウェア命令に基づいているということです。

関数内の通常のローカル変数は、すでに個々のスレッドに固有です。複数のスレッドから同時にアクセスできるのは、静的データ、グローバルデータ、またはその他のデータだけであり、それを保護するためのロックが必要です。

于 2009-01-17T06:08:44.420 に答える
0

ロックを操作するメカニズムは、ロックへのアクセスを制御します。

ロック プリミティブは、プロセッサ間で変更を伝達できる必要があるため、通常はバス操作、つまりメモリの読み取りと書き込みの上に実装されます。また、それを要求しようとする 2 つのスレッドがその状態を壊さないように構造化する必要もあります。簡単ではありませんが、通常、OS が実装するロックが複数のスレッドによって破損されることはないと信頼できます。

于 2009-01-21T17:14:34.257 に答える