0

質問はX86/LINUX環境に限定されています。

1 つのスレッドがロック付きの変数を書き込み、他のスレッドがロックなしでこの変数を読み取ります。書き込みスレッドがロック解除されたとき、他のスレッドはすぐに新しい値を読み取ることができますか?

 volatile int a=0;

   /* thread 1(write) */    
   lock();  
   a = 10;  
   unlock();  

   /* thread 2(read) */  
   printf("%d",a);

1 つのスレッドがロック付きの変数を読み取り、別のスレッドがロックなしでこの変数を書き込みます。書き込みが完了した後に読み取りスレッドが読み取ったとき、新しい値をすぐに読み取ることができますか?

   volatile int a=0;

   /* thread 1(read) */  
   lock();  
   printf("%d",a);  
   unlock();  

   /* thread 2(write) */  
   a = 10;  
4

3 に答える 3

2

可能ですが、保証されていません。どちらの場合も、未定義の動作があります。複数のスレッドがオブジェクトにアクセスし、少なくとも1つのスレッドがオブジェクトを変更するとすぐに、すべてのアクセスを同期する必要があります。そうしないと、未定義の動作が発生します。

これは、C++11とPosixによると当てはまります。LinuxはPosixのルールに従います。VC ++の一部のバージョンではvolatile、アトミックセマンティクスで拡張されています。(Posixでは、 volatile懸念シグナルおよびlongjmp/に関連する唯一のセマンティクスsetjmpです。これはまったく無関係であり、スレッド化ではほとんど無視されます。)

于 2012-04-23T10:56:22.910 に答える
2

1 つのスレッドがロック付きの変数を書き込み、他のスレッドがロックなしでこの変数を読み取ります。書き込みスレッドがロック解除されたとき、他のスレッドはすぐに新しい値を読み取ることができますか?

はい、できますが、書き込みが開始される前にすべての読み取りスレッドが読み取られないようにするにはどうすればよいでしょうか?

1 つのスレッドがロック付きの変数を読み取り、別のスレッドがロックなしでこの変数を書き込みます。書き込みが完了した後に読み取りスレッドが読み取ったとき、新しい値をすぐに読み取ることができますか?

はい。でも、読み取りと書き込みの順序を保証するものは何ですか?

特定のシナリオで操作を実行する必要があるため、ここで何らかの形式の同期を提供する必要があります。最も簡単なのは、 Semaphoreのようなシグナリング カウンターを使用することです。
シーケンスの順序付けを提供しないことに注意しvolatileてください。コンパイル部分での最適化が保証されないだけなので、順序付けは依然としてあなたの責任です。

于 2012-04-23T10:27:12.447 に答える
0

気をつけて。変数がロックで囲まれているからといってコードの他の部分でa. 最初の例では、変更されるコードへのアクセスをロックしますaが、その後unlock()、保護されていない読み取りを使用します。その読み取りの直前または最中に、別のスレッドが値を変更してa、まったく予想外の予測不可能な結果を​​もたらす可能性があります。

つまり、変数自体へのアクセスをロックするのではなく、コード内の特定のパスを相互に排他的に制限します。

また、あなたの使用volatileは懸念されます。なぜそれを使用したのかはわかりませんが、期待していたものは得られないと思います。詳細な説明については、こちらをお読みください。

于 2012-04-23T10:41:01.777 に答える