Objective-C IOS多線程之GCD深入理解

来源:http://www.cnblogs.com/smithjackyson/archive/2016/03/10/5262123.html
-Advertisement-
Play Games

在 GCD 中,加入了兩個非常重要的概念:任務和隊列一個線程是可以擁有多個執行隊列的,所有任務是添加到隊列中等待執行的主隊列是特殊的串列隊列,自己創建的隊列可以指定串列或並行,全局隊列是並行隊列 任務:即操作,你想要乾什麼,說白了就是一段代碼,在 GCD 中就是一個 Block,所以添加任務十分方便


在 GCD 中,加入了兩個非常重要的概念:任務和隊列
一個線程是可以擁有多個執行隊列的,所有任務是添加到隊列中等待執行的
主隊列是特殊的串列隊列,自己創建的隊列可以指定串列或並行,全局隊列是並行隊列

任務:即操作,你想要乾什麼,說白了就是一段代碼,在 GCD 中就是一個 Block,所以添加任務十分方便。
任務有兩種執行方式: 同步執行和非同步執行,他們之間的區別主要在於會不會阻塞當前線程

首先看下麵這兩個例子:

1、

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"%d",[[NSThread currentThread] isMainThread]);
});

2、

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"%d",[[NSThread currentThread] isMainThread]);
});

兩個例子都是創建一個新隊列,之間的區別隻在於前者是以同步運行,後者則是非同步
結果前者列印出1,後者則是0。

我們分析一下,這裡同步的意思其實是對於線程的所有執行隊列而言,就是說同步執行時,除了block任務,在同一個線程執行的其他隊列全部暫停執行,當block任務執行完成後,其他隊列任務才恢復執行。(這裡還有個要特別註意的,就是系統在判別是否要暫停隊列的執行時,是按照block任務是否在隊列頭,如果不是就停止隊列執行

上面例子1中創建一個新隊列,block任務在第一個,即隊列頭,以同步執行時就是所有在主線程執行的隊列會暫停執行(除了block任務所在隊列)。例子2因為是創建一個新隊列,又是非同步執行,所以會創建一個新線程執行,所以列印出來的0,也就是主線程上的隊列照常執行。

為了證明我上面的假設,我舉個例子:

3、

dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
NSLog(@"%d",[[NSThread currentThread] isMainThread]);
});

4、

dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"%d",[[NSThread currentThread] isMainThread]);
});

上面兩個例子都是將block任務添加到主隊列,但是結果卻不同,例子3結果是永遠不會執行列印語句,程式不會再執行了,例子4正常執行,且在主隊列中
結論:不是非同步就一定會開啟新的線程

例子3因為將block任務添加到主隊列中,此時主隊列已經有任務(當前語句沒有執行完,所以block任務不是將要執行的任務),根據前面的系統判定,主隊列被暫停執行,此時前面的任務無法完成,後面的block任務也無法完成,造成死迴圈
例子4中將任務添加到主隊列中,雖然是非同步操作,但是並不會開啟新的線程,因為在主隊列中,要在主線程中執行,而非同步操作不會將線程阻塞,所以隊列照常執行。

結論:同步會讓系統判定暫停執行所有不以block塊任務為第一任務的隊列(即如果block塊任務不在隊列頭,那麼block塊任務所在的隊列也會暫停執行),且同步一定不會開啟新線程,因為GCD覺得既然其它隊列暫停執行,block塊任務就可以在當前線程執行了,沒有必要開啟新線程。而非同步則系統不會進行判定,但是不一定會開啟新線程,這個跟隊列有關,如果是新創建的隊列,那麼GCD就會開啟新線程,如果加入已有的隊列,那麼就會在隊列所在的線程中執行。

簡單來講,同步操作那麼block塊任務會在當前線程中執行,比如上面在主線程中進行同步操作,那麼一定就是在主線程中執行,不管隊列是主隊列還是全局隊列或者自己創建的隊列。如果是非同步操作的話,那麼就要分情況來看了,如果是主隊列,那麼就是在主線程中執行,如果是全局或自己創建的隊列,那麼就是在新創建的線程中執行,全局隊列會根據任務自動創建一個或多個線程,自己創建的隊列就是根據參數設定和任務進行分配。


至於串列和並行,串列和並行是針對同一個隊列中的任務而言的,當使用串列,那麼隊列里的那麼隊列里的任務最多只能使用一個線程運行,即同一時刻只有一個任務在執行,如果是並行,那麼系統會根據隊列里的任務自動分配線程執行,最大線程數跟據參數設定

 

 


轉載請註明:作者SmithJackyson


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 可能是由於粘貼網頁上的代碼的時候兩行之間的回車引起的,兩行之間重新輸入回車就行...。。。刪掉重新寫一遍就ok了
  • 個人筆記與總結。
  • 博客園官方API 花樣作死封裝網路層(iOS或OSX) === 前一段時間通過孤獨的貓咪神瞭解到博客園有官方API,據說今年四月份下旬的樣子推出吧。(道聽途說!)...我小小的申請去測試了下,打算也用博客園官方的API寫一點兒東西,例如OSX和iOS的小軟體。。在之前博客園官方的API也是公開的,舊
  • 我的天! 折騰了好久終於搭建成功了第一個項目。 項目環境: Windows 7 家庭普通版 64位 Android studio 1.5.1 OpenCV-2.4.9-android-sdk 基於Android studio上OpenCv開發環境的配置請參考 http://www.cnblogs.c
  • 最近開發android軟體客戶要安裝在樂視TV上,而且要求是開機自啟。我很天真的以為寫一個廣播接收類接收開機廣播就可以了,可是根本不會,有的設備就是不可以接收到開機廣播,於是各種百度搜索。大神們說是只有系統軟體才可以監聽到開機廣播,於是我要把自己的應用升級為系統應用..... 就先說如何將自己的應用
  • 本文譯自iOS 7 Blur Effects with GPUImage。 iOS 7在視覺方面有許多改變,其中非常吸引人的功能之一就是在整個系統中巧妙的使用了模糊效果。許多第三方應用程式已經採用了這樣的設計細節,並以各種奇妙的和具有創造性的方式使用它。 本文將通過幾種不同的技術來實現iOS 7中的
  • 本文譯自:Cookbook: Moving Table View Cells with a Long Press Gesture 目錄: 你需要什麼? 如何做? 如何將其利用至UICollectionView上? 何去何從? 本次的 cookbook-style 教程中介紹如何通過長按手勢來移動 t
  • 在android開發中,常常有聯繫人頁面,在這篇和大家分享一下項目中剛剛添加的聯繫人頁面,代碼直接從項目中提取出來,沒有太多時間修改;使用 StickyListHeaders-master 開源項目及SiderBar。先上圖看看效果。 同時用的三方jar包有:glide pinyin4j。原理還是相
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...