IOS開發之多線程,ios多線程

來源:互聯網
上載者:User

IOS開發之多線程,ios多線程

前言:這篇GCD的博文是本人閱讀了很多海內外大神的關於GCD的文章,以及結合之前自己對GCD的粗淺的認識,然後取其精華,去其槽粕,綜合起來的筆記,而且是儘可能的以通熟易懂的並且是正確的理論論述方式呈現給大家,已經是儘可能的讓大家掌握多線程的知識以及GCD的使用技術。最後的附錄中,我將會給出所有本人閱讀的大神寫的關於多線程或者是GCD的文章連結,大家感興趣的,可以去參考和學習。

本篇博文:持續更新,還未更新完。

 

相關基本概念

1、什麼是GCD?

iOS實現提供實現多線程的方案有:NSThread、NSOperation、NSInvocationOperation、pthread、GCD。

在iOS所有實現多線程的方案中,GCD應該是最有魅力的,而且使用起來也是最方便的,因為GCD是蘋果公司為多核的並行運算提出的解決方案。

GCD是Grand Central Dispatch的簡稱,它是基於C語言的。使用GCD,我們不需要編寫線程代碼,其生命週期也不需要我們手動管理,定義想要執行的任務,然後添加到適當的調度隊列,也就是dispatch queue。GCD會負責建立線程和調度任務,系統直接提供線程管理。

 

2、任務(Task)

一段代碼塊,執行之後能夠實現的一段商務邏輯過程。一般用閉包或者叫block,來包含它。執行任務,就需要將這個閉包或者block交給隊列,然後讓隊列 先進先出(FIFO) 的順序取出來,放進線程中執行。

 

3、隊列(Queue)

我們需要瞭解隊列的概念,GCD提供了dispatch queues來處理代碼塊,這些隊列管理所提供給GCD的任務並用FIFO順序執行這些任務。這樣才能保證第一個被添加到隊列裡的任務會是隊列中第一個開始的任務,而第二個被添加的任務將第二個開始,如此直到隊列的終點。

  • 串列(Serial)隊列

    串列隊列 中的任務會根據隊列定義 先進先出(FIFO) 的順序取出來一個,執行一個,執行完瞭然後取出下一個任務,這樣一個一個的執行。

    串列隊列圖:

   

  • 並發(Concurrent)隊列

    並發隊列 中的任務也會根據隊列定義 先進先出(FIFO)的順序一個個取出來,但是與串列隊列不同的是,並發隊列取出一個任務會放到別的線程中開始執行,先不管這個線程是同步線程還是非同步線程,並發隊列並不是等線程中的任務執行完了而是取完了這個任務,就會立刻接著從並發隊列中取下一個任務放到別的線程中開始執行。由於取任務的速度很快,忽略不計,看起來,好像所有任務都是同時開始執行任務的。但是,任務又長又短,任務執行結束的順序你是無法確定的,有可能那個最短的任務先執行完畢了。

    並發隊列圖:

   

補充:並發代碼的不同部分可以“同步”執行。然而,該怎樣發生或是否發生都取決於系統。多核裝置通過並行來同時執行多個線程;然而,為了使單核裝置也能實現這一點,它們必須先運行一個線程,執行一個環境切換,然後運行另一個線程或進程。這通常發生地足夠快以致給我們並發執行地錯覺,如所示:

  

 

4、隊列的類型(Queue Types)

系統提供的:

  • 一個主隊列(main queue),是串列隊列。

    和其它串列隊列一樣,這個隊列中的任務一次只能執行一個。然而,它能保證所有的任務都在主線程執行,而主線程是唯一可用於更新 UI 的線程。這個隊列就是用於發生訊息給 UIView 或發送通知的。

   

    在使用主線程串列隊列時,我們只通過dispatch_get_main_queue方法來擷取即可,我們不需要管理其記憶體問題。

  • 四個全域調度隊列(Global Dispatch Queues),都是並行隊列

    四個全域隊列有著不同的優先順序:background、low、default 以及 high。要知道,Apple 的 API 也會使用這些隊列,所以你添加的任何任務都不會是這些隊列中唯一的任務。

   在使用全域並發隊列時,我們只通過dispatch_get_global_queue方法來擷取即可,我們不需要管理其引用。

  • 你也可以建立自己的串列隊列或並發隊列。

   

總結:這就是說,至少有五個隊列任你處置:主隊列、四個全域調度隊列,再加上任何你自己建立的隊列。

以上是調度隊列的大架構!

 

5、線程

  線程分為兩種:Synchronous vs. Asynchronous 同步 vs. 非同步。

  GCD建立同步線程和非同步線程的方式:

  

  這裡會有兩個東西要說:同步函數和非同步函數。我們的C語言基礎就學了函數,函數用大括弧包含了一段代碼塊,當這個函數執行完畢就會返回,可以是返回void或者返回具體某個資料值,同時也代表著這個函數的執行完畢。那麼線程中的函數,當然是包含了任務的,這個任務就是閉包或者叫block。同步函數和非同步函數的區別就在,同步函數需要在完成了它預定的任務後才返回,而非同步函數會立即返回,也就是說非同步函數預定的任務會完成但不會等它完成就立即返回。

  另外,同步線程是不具備建立子線程的能力的,一般情況下,同步線程的任務會在唯一的主線程中執行,也就是說唯一的(main)主線程就成了同步線程。而非同步線程是具備建立子線程的能力的,一般情況下,非同步線程就是(main)主線程以外的線程,不唯一,會有多個,具體多少個,具體是哪些線程,如果是通過GCD建立,全部由GCD決定。關於能建立的子線程的最大個數,這個就需要根據裝置的CPU的能力了,比如下面是本人用真機,通過使用GCD建立了多個非同步任務,並添加進並發隊列執行測試的結果:

  

  可以發現,我建立了8個非同步任務,GCD根據裝置的極限,建立了三個子線程,分別是線程2、3、4,然後由它們隨機執行任務。其中線程4執行了四個任務,線程2和線程3分別執行了兩個任務。

  那麼,同步還是非同步,這兩個術語是需要多個函數任務之間對比來論述的,這樣會更好理解。比如說同步,當線程執行一個同步函數任務的時候,這個線程會停下來,也就是所謂的"當前這個線程阻塞"了,當前線程需要等待這個函數執行完畢返回了值,也表示這個函數中的任務完全執行完畢了,這個線程才會繼續執行下去,去執行下一個函數任務,所以這樣的線程也叫同步線程。而非同步函數所在的線程就不一樣了,線程開始執行一個非同步函數任務的時候,因為非同步函數立即返回了,雖然這個函數任務可能還沒執行完畢,但是返回了,這個線程就會繼續執行下一個函數任務,由於這個過程很快,快到可以忽略不計任務執行開始的先後順序,快到感覺好像都是同時開始執行任務的,所謂的"非同步線程同時執行多個任務"就是這麼來的。

 

注意:

  不要將耗時操作放在主線程中,凡是跟UI相關的操作都是放在主線中處理

  耗時操作應該放在子線程(後台線程,非主線程)

 

6、總結一下同時使用隊列和線程

好,下面我們來看看這個圖,可能會和你們別處看的有點不一樣,這是本人根據上面理論進行了適當的修改:

  

6-1、串列隊列+同步:

  假設一堆任務放在串列隊列中。

  因為串列隊列是先進先出FIFO隊列,而且串列隊列是需要前面取出的一個任務執行完了之後,才接著取下一任務。

  因為同步(sync)沒有開啟新線程的能力。

  所以,這一堆任務,將會在main主線程中,一個執行完畢之後接著下一個開始執行直到完畢,就這樣按順序執行任務。

  會阻塞當前線程。

  驗證代碼:

  

  列印結果:

  2016-03-13 15:51:04.970 多線程[25106:632356] 當前線程是:<NSThread: 0x7fe28bc025b0>{number = 1, name = main}
  2016-03-13 15:51:06.974 多線程[25106:632356] 當前線程是:<NSThread: 0x7fe28bc025b0>{number = 1, name = main}
  2016-03-13 15:51:08.979 多線程[25106:632356] 當前線程是:<NSThread: 0x7fe28bc025b0>{number = 1, name = main}
  2016-03-13 15:51:10.980 多線程[25106:632356] 當前線程是:<NSThread: 0x7fe28bc025b0>{number = 1, name = main}

6-2、並發隊列+非同步:

 

6-3、

6-4、

 

 

 

附錄:很好的GCD學習的網頁連結

1、GCD這塊已經開源,地址http://libdispatch.macosforge.org

2、唐巧的技術部落格:《使用GCD》,地址:http://blog.devtang.com/2012/02/22/use-gcd/

3、大神翻譯自國外IOS很不錯的學習網站文章《Grand Central Dispatch In-Depth: Part 1/2》:https://github.com/nixzhu/dev-blog

4、標哥的技術部落格:《GCD由淺入深學習》:http://www.henishuo.com/gcd-multiple-thread-learn/

5、土土哥的《GCD使用經驗與技巧淺談》:http://tutuge.me/2015/04/03/something-about-gcd/

6、YouXianMing老師的《Grand Central Dispatch (GCD) Reference》:http://www.cnblogs.com/YouXianMing/p/3600763.html

7、《關於IOS多線程,你看我就夠了》:http://www.jianshu.com/p/0b0d9b1f1f19

8、《細說GCD(Grand Central Dispatch)如何使用》 :http://www.jianshu.com/p/fbe6a654604c

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.