10

我的應用程序大量使用GCD,並且幾乎所有東西都被分派到由調度處理的小任務中。但是,底層數據模型大部分是讀取的,只是偶爾寫入。用GCD讀寫鎖定

我目前使用鎖來防止在讀取時更改關鍵數據結構。但今天看了更多鎖之後,我發現了NSConditionLock和一些關於讀寫鎖的頁面。後者正是我所需要的。

我發現這個實現:http://cocoaheads.byu.edu/wiki/locks。我的問題是,這個實現與GCD一起工作,看到它使用PThreads?

回答

20

它仍然有效。 pthreads是線程API,它是Mac OS X上所有其他線程使用API​​的基礎。(在那之下有Mach線程激活,但這是SPI,而不是API)。無論如何,pthreads鎖並不真的需要你使用pthreads線程。

但是,GCD爲iOS 5提供了一個更好的選擇:dispatch_barrier_async()。基本上,你有一個私人的併發隊列。您以正常方式將所有讀取操作提交給它。您使用屏障例程向其提交寫入操作。噹噹!讀寫鎖定。

如果您有權訪問WWDC 2011 session video for Session 210 - Mastering Grand Central Dispatch,則可以瞭解更多信息。

+1

啊,我已經讀過關於屏障的信息,但當時想不出一個實際的應用程序(當時我幾乎沒有使用多線程)並忘記了所有關於它們的內容。謝謝,我會試着看看我能否使用它! – 2012-04-19 19:09:51

+3

Mike Ash還提供了一個很好的例子,說明如何使用GCD完成讀寫器同步。 http://www.mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html – 2013-04-03 07:15:03

1

您可能還想考慮爲所有讀/寫操作維護一個串行隊列。然後,您可以向該隊列寫入數據,以確保對數據模型的更改立即應用,並確保您在應用中保持良好的性能。

既然你有一個單一的串行隊列,所有的讀寫操作都發生,你確保在寫入過程中不會發生讀操作。這比鎖的成本低得多,但這意味着你不能同時執行多個「讀取」操作。這不太可能對大多數應用程序造成問題。

使用dispatch_barrier_async()可能意味着您編寫的文件需要耗費大量的時間才能真正提交,因爲隊列中的所有預先存在的任務必須在您的barrier塊執行之前完成。

+0

嗯,我甚至沒有意識到串行隊列上的異步調度是可能的。這聽起來像一個有趣的想法......所有讀取都是相當小的編輯,但寫入通常意味着讀取,編輯並再次保存數據。 – 2012-05-06 09:17:26

+5

通常情況下,你會做與本文建議的相反的內容。讀取通常必須同步提交,因爲在返回給調用者之前,您通常需要獲得結果。寫操作可以異步完成,因爲調用者只關心來自外部的狀態可觀察值與已寫入的日期是否一致,這是因爲在隊列是串行的寫入完成之前不能進行讀操作。如上所述,這對多個讀者沒有幫助。 – 2012-05-12 03:01:39