2017-10-02 1 views
1

私は理解しておくと、スレッドセーフな読み書きを提供する必要があります_predictionsのコードを持っています。私のisolationQueueは並行キューであり、そのままにする必要があります。このキューで複数の独立した非同期操作を呼び出して、さまざまな画像の予測を計算します。さまざまなコール間の唯一の共有アイテムは、予測が設定されている場合です。ゲッターとセッターのためのカスタム並行キュー同期のレース条件

var isolationQueue = DispatchQueue.global(qos: .default) 
    var _predictions: [Int:[Prediction]] = [:] 

    var predictions:[Int: [Prediction]] { 
    get { 
     var result: [Int: [Prediction]]! 
     isolationQueue.sync { 
     result = _predictions 
     } 
     return result 
    } 
    set(value) { 
     isolationQueue.sync { 
     self._predictions = value 
     } 
    } 
    } 

しかし、なんらかの理由で、Thread Sanitizerがゲッターとセッターの競合状態を検出しているようです。

enter image description here enter image description here

私は何かが足りないのですか?

+1

isolationQueueはどのように定義されていますか?それは*シリアル*ディスパッチキューですか? –

+0

が更新しました。それはグローバルなので、私はそれが同時に起こると信じています。 'sync'を使った' var isolationQueue = DispatchQueue.global(qos:.default) ' –

答えて

1

グローバルディスパッチキューは、同時キューキューであるため、リソースの同時アクセスを防ぐためには にすることはできません。

あなたはその目的のために、独自のシリアルディスパッチキュー定義する必要があります:あなたのケースのために

var isolationQueue = DispatchQueue(label: "my.queue.identifier") 
+0

は、並行キューで実行されている間にリソースにアクセスする他のスレッドから保護しません。並行キューでのシリアルアクセスを保証する方法はありますか? –

+0

@RezaShirazian: 'sync'は、呼び出しスレッドが完了を待つことを意味しますが、異なるスレッドから送出されたブロックは同時に実行できます。以下は4つの可能な組み合わせの概要です:https://stackoverflow.com/questions/19179358/concurrent-vs-serial-queues-in-gcd –

+0

'sync'をどうすればいいですか?私の 'isolationQueue'がシリアル' sync'の場合、このケースでは多くの意味がないようです。 –

0

を、DispatchSemaphore()を使用することは簡単で、オーバーヘッドが少ないです。

var isolationSem = DispatchSemaphore(value: 1) 
var _predictions: [Int:[Prediction]] = [:] 

var predictions:[Int: [Prediction]] { 
    get { 
    var result: [Int: [Prediction]]! 
    isolationSem.wait() 
    result = _predictions 
    isolationSem.signal() 
    return result 
    } 
    set(value) { 
    isolationSem.wait() 
    self._predictions = value 
    isolationSem.signal() 
    } 
} 

のようなコードになりますがDispatchSemaphoreが適切でない場合のためにthisを参照してください。

関連する問題