2016-06-28 95 views
0

我嘗試了一個簡單的例子來學習使用dispatch-barrier async。基本上,下面是一個ViewDidLoad的單視圖iOS應用程序。將三個任務提交給併發隊列。其中兩個讀取變量,而第三個寫入變量。dispatch_barrier_async中的代碼沒有執行

我看到寫入永遠不會執行(即X = X + 10永遠不會執行)。如果我只是使用dispatch_async(而不是像dispatch_barrier_async中保護它)那樣提交它,如最後一段代碼所示,作品。 (令人驚訝的是,即使當我沒有使用disaptch_barrier_async保護它時,在2次讀取X的同時寫入X也沒有問題)。

- (void)viewDidLoad { 
[super viewDidLoad]; 
// Do any additional setup after loading the view, typically from a nib. 
dispatch_queue_t backgroundQueue; 

__block int X = 10; 

backgroundQueue = dispatch_queue_create("com.smarthome.readwriteQ", DISPATCH_QUEUE_CONCURRENT); 

dispatch_async(backgroundQueue, ^{ 
    while (1) { 
     NSLog(@"Task 1: X = %d",X); 
     [NSThread sleepForTimeInterval:4]; 
    } 
}); 

dispatch_async(backgroundQueue, ^{ 
    while (1) { 
     NSLog(@"Task 2: X = %d",X); 
     [NSThread sleepForTimeInterval:4]; 
    } 
}); 

//This does not work 
dispatch_barrier_async(backgroundQueue,^(void){ 
    while (1) { 
     X = X + 10; 
     NSLog(@"Task 3: After Writing X = %d",X); 
     [NSThread sleepForTimeInterval:2]; 
    } 
}); 

//This works 
dispatch_async(backgroundQueue,^(void){ 
    while (1) { 
     X = X + 10; 
     NSLog(@"Task 3: After Writing X = %d",X); 
     [NSThread sleepForTimeInterval:2]; 
    } 
}); 
} 

我想我沒有正確理解dispatch_barrier_async。任何指針將不勝感激。

回答

2

documentation說:

當它遇到一個屏障,併發隊列延遲阻擋塊,直到阻擋結束執行前提交的所有塊執行(或任何其它功能塊)。

您提交了兩個塊,將從未完成執行,然後提交障礙塊。所以GCD永遠不會執行障礙塊。

+0

謝謝,有道理。 –

+0

這是否意味着如果我有幾個長時間運行的任務,並且每個任務讀取或修改共享變量,那麼我至少需要兩個分派隊列:一個或多個運行任務的隊列,然後是一個用於提交的隊列讀取或寫入共享變量的任務? –

+0

這可能是有道理的,當然。 –