3

私のCocoa/iOSアプリケーションには、静的double変数(これを呼びましょうfoo)があります。これは次のようにする必要があります。

  1. バックグラウンドスレッドでアプリの一部によって更新されました
  2. メインスレッドで私のアプリの別の部分によって読まれました

へのアクセスを同期するための最も軽量な方法を探していますfoo

:これらの場合の最も簡単な解決策は、通常、1つのスレッドのみが変数にアクセスするようにコードを調整することであり、したがって同期は必要ありません。fooこの場合、単一のスレッドへのアクセスを制限することは不可能であると私が判断したと仮定しましょう(おそらく、ステップ1で実行されるアクションが非常に迅速に発生するため、スレッドの切り替えは望ましくありません)。foo「 1つのスレッドへのアクセスを制限する」という回答で応答しないでください。私はそれに代わるものを探しています。


私の現在の理解では、volatile変数を使用することがへのアクセスを同期する最も軽量な方法fooです。したがってfoo、次のように宣言されます。

static volatile double foo = 60.0;

バックグラウンドスレッド書き込みコードは次のようなものです。

foo = 90.0;

メインスレッドの読み取りコードは次のようなものです。

double bar = 0.0;
bar = foo;
// use bar here …


いくつかの質問:

  1. fooメインスレッドは、バックグラウンドスレッドに書き込まれた後の更新された値を確認することが保証されていますか(foo宣言されている場合volatile)?IOW、2つのスレッドが互いの読み取り/書き込み操作の結果を確認できるようにするために十分なことをしましたか?
  2. この状況では、ブロックやのようなミューテックスロックよりも、値に使用volatileする方が高速/軽量/好ましいと思います。本当?IOW、この特定のケースに最適なソリューションはありますか?double@synchronizedNSLockvolatile
4

4 に答える 4

3

1)いいえvolatileここではアトミックプリミティブの代わりにはなりません。閉じますが、完全ではありません。

2)問題は、あなたが今知っているようにvolatile、それは正しくありません。

_Atomic理想: C11や<atomic>C ++ 11など、最新のアトミック言語機能にアクセスできる場合があります。

そうでない場合は、64ビットの整数関数とアトミック関数を使用して値で読み取り、に転送するdoubleか、単純なスピンロックまたはおそらくスピンロックを使用することができますpthread_mutex_t(スピンロックには十分注意してください)。

ただし、オプションの場合は、値の変更をメインスレッドの実行ループに投稿する方がよい場合があります。

于 2012-08-23T17:09:39.850 に答える
3

Cocoaには、このためのプリミティブが組み込まれています。OSAtomic.hの内容をチェックしてください

OSAtomicCompareAndSwap64Barrierアトミックな方法で(正しく整列され、揮発性の)doubleを書き込むために使用できます。OSMemoryBarrierまた、最新の値を確認するために、読む前に読む必要があります。32ビットアーキテクチャはおそらくアトミックな方法で64ビットdoubleを読み取らないため、これは64ビットアーキテクチャでのみ機能すると思います。

于 2012-08-23T19:29:30.057 に答える
2

これにはGCDを使用して、変数へのアクセスを管理する同時ディスパッチキューを作成します。読者は簡単にできます

__block double bar;
dispatch_async(foo_queue, ^{ bar = foo; });

書き込みはディスパッチバリアを使用できます。

dispatch_barrier_async(foo_queue, ^{ foo = someOtherFoo; });

の呼び出しdispatch_barrier_asyncは、保留中のリーダーブロックが完全に実行されることを保証します。その後、書き込みブロックが実行され、値が更新されてから、リーダーブロックが実行されます。

これは、WWDCの一部のGCDビデオでAppleが推奨するパターンです。

于 2012-08-23T18:15:40.333 に答える
1

GCCには、必要なものになる可能性のあるアトミックプリミティブがあります。gcciOS用にビルドするときにこれらがどれだけうまくサポートされているかはわかりません。おそらく、、、llvm-gccまたはを使用するかどうかによって異なりますclang

于 2012-08-23T17:11:56.207 に答える