1

讀取變量,這可能聽起來新手的問題,反正進出口新的GCD,GCD:如何編寫,並從兩個線程

我創建和運行這兩個以下線程。第一個將數據放入ivar mMutableArray,第二個從中讀取數據。我如何鎖定和解鎖線程以避免崩潰並保持代碼線程安全?

// Thread for writing data into mutable array 
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); 
if (timer) { 
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * interval), interval * NSEC_PER_SEC, leeway); 
    dispatch_source_set_event_handler(timer, ^{ 
     ... 
     // Put data into ivar 
     [mMutableArray addObject:someObject]; 
     ... 
    }); 
    dispatch_resume(timer); 
} 

// Thread for reading from mutable array 
dispatch_source_t timer1 = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); 
if (timer1) { 
    dispatch_source_set_timer(timer1, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * interval), interval * NSEC_PER_SEC, leeway); 
    dispatch_source_set_event_handler(timer1, ^{ 
     ... 
     if (mMutableArray) { 
      // Read data from ivar 
      SomeObject* someobject = [mMutableArray lastObject]; 
     } 
     ... 
    }); 
    dispatch_resume(timer1); 
} 

回答

0

你仍然可以在你的關鍵部分使用@Synchronized與GCD

+1

爲了清楚'@synchronized',GCD不執行「停止世界」的同步。它只會**停止所有其他線程訪問您的關鍵部分/ s **。這通常是你想要的。 – Barry

1

我用我的項目互斥體,我與它是如何工作的時刻很高興。

創建互斥量並初始化它

pthread_mutex_t *mutexLock; 
pthread_mutex_init(&_mutex, NULL); 

然後把鎖在你的代碼中,一旦第二線程試圖獲得鎖,它會等待,直到鎖被第一線程再次釋放。請注意,您仍然可能需要檢查第一個線程是否實際上是寫入該線程的線程。

pthread_mutex_lock(self_mutex); 
{ 
    ** Code here 
} 
pthread_mutex_unlock(self_mutex); 
5

您正在使用它是錯誤的,通過鎖定訪問變量,您只是失去了GCD的任何好處。創建一個與您要修改的變量(在本例中爲可變數組)相關聯的單個串行隊列。然後使用該隊列對其進行寫入和讀取,這將以保證的串行順序發生並具有最小的鎖定開銷。您可以在http://www.fieryrobot.com/blog/2010/09/01/synchronization-using-grand-central-dispatch/的「Asynchronous setters」中閱讀更多信息。只要您通過關聯的調度隊列訪問共享變量,您就不會遇到併發問題。

+1

是的,鎖定非常昂貴,並且在串行調度隊列中與共享資源進行交互是我在應用程序中構建事物的方式。它在幾個案例中導致了顯着的性能改進。您也可以將此與調度信號相結合,以避免在某些情況下在隊列中構建塊。 –

+0

在大多數性能至關重要的代碼中,讀鎖的處理方式與寫鎖不同。通常,您需要一個可重入讀鎖(類似於'NSRecursiveLock')和一個單寫鎖(類似於'NSLock')。 '@ synchronized'與讀鎖('NSRecursiveLock')最相似。用'@ synchronized' automagic異常處理贏得大勝。 – Barry