2017-02-03 136 views
1

我是一名Android工程師,嘗試移植一些使用5個SERIAL調度隊列的iOS代碼。我想確保我以正確的方式思考事情。瞭解dispatch_queues和同步/異步調度

  • dispatch_sync到串行隊列基本上使用該隊列作爲同步queue-只有一個線程可以訪問它,並且被執行的塊可以作爲一個關鍵區域被認爲。它立刻發生在當前thread-

    get_semaphore() 
    queue.pop() 
    do_block() 
    release_semaphore() 
    
  • dispatch_async它相當於一個串行queue-執行在另一個線程塊,並立即讓當前線程的回報。然而,由於它是一個串行隊列,它承諾這些異步線程中的一個將一次執行(下一次對dispatch_async的調用將一直等到所有其他線程完成)。該塊也可以被認爲是一個關鍵區域,但它會在另一個線程上發生。所以和上面的代碼一樣,但是它首先傳遞給工作線程。

我是否關閉了,或者我是否正確地弄清楚了?

回答

1

這感覺就像是一種過度複雜的思維方式,而且有很多描述中的小細節並不完全正確。具體來說,「它立即發生在當前線程上」是不正確的。

首先,讓我們退一步:dispatch_asyncdispatch_sync之間的區別只是是否當前線程等待與否。但是當你將一些東西發送到串行隊列時,你應該總是想象它在GCD自己選擇的單獨的工作線程上運行。是的,作爲優化,有時dispatch_sync將使用當前的線程,但您無法保證這一事實。

其次,當你討論dispatch_sync時,你會說「立即」運行。但決不立刻。如果某個線程對某些串行隊列執行dispatch_sync,則該線程將阻塞,直到(a)該串行隊列上當前正在運行的任何塊完成; (b)該串行隊列的任何其他排隊塊運行並完成; (c)顯然,線程A本身調度的塊運行並完成。

現在,當您使用串行隊列進行同步時,對內存中的某個對象進行某種線程安全訪問,通常該同步過程非常快,因此等待的線程通常會被阻塞的時間可以忽略不計其派出的區塊(以及任何先前分派的區塊)完成。但總的來說,它會立即運行,這是誤導性的。 (如果它總是可以立即運行,那麼你不需要隊列來同步訪問)。


現在關於「關鍵區域」你的問題的會談,而我假設你正在談論的一些代碼位,爲了保證線程安全或其他一些原因類似,必須同步。因此,在運行此代碼以進行同步時,唯一的問題是dispatch_sync vs dispatch_async是當前線程是否必須等待。例如,一種常見模式是,可能會向某個模型寫入dispatch_async(因爲在繼續之前不需要等待模型更新),但dispatch_sync會讀取某個模型(因爲您顯然不想繼續直到返回讀取值)。

該同步/異步模式的進一步優化是讀寫器模式,其中併發讀取是允許的,但併發寫入不是。因此,您將使用併發隊列dispatch_barrier_async寫入(實現類似於寫入的串行行爲),但使用dispatch_sync讀取(享受與其他讀取操作相關的併發性能)。

+0

關鍵區域是關鍵部分的另一個名稱:https://en.wikipedia.org/wiki/Critical_section –

+0

是的,這就是我認爲你的意思。在iOS中我們稱之爲需要「同步」。請參見[線程編程指南:同步](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW1 )。但是,這早於GCD,這在[併發編程指南:消除基於鎖的代碼](https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/ThreadMigration/ThreadMigration.html#//apple_ref/DOC/UID/TP40008091-CH105-SW3)。 – Rob

+0

是的。所以我立即說出了一些sl sl,但我做了正確的事情。幸運的是,我認爲我可以簡化爲Android實現的1個消息隊列,而不是圍繞核心數據通知構建的架構使事情變得更容易。 –

1

要選擇nits,dispatch_sync不一定會在當前線程上運行代碼,但如果它不運行,它仍會阻塞當前線程,直到任務完成。如果您依賴線程ID或線程本地存儲,這種區別只有潛在的重要性。

但是,否則,是的,除非我錯過了一些微妙的東西。

+0

很高興知道。修正答案。 – dgatwood