【iOS面試系列-2】多線程中同步、非同步和串列、並行之間的邏輯關係(必考,必須掌握)

来源:http://www.cnblogs.com/Hanzo/archive/2016/09/12/5866804.html
-Advertisement-
Play Games

API-https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/index.html#//apple_ref/doc/uid/TP40008079 一、同步、非同步和 ...


API-https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/index.html#//apple_ref/doc/uid/TP40008079

 

一、同步、非同步和串列、並行

     任務串列執行就是每次只有一個任務被執行任務併發執行就是在同一時間可以有多個任務被執行。

     一個同步函數只在完成了它預定的任務後才返回。一個非同步函數,剛好相反,會立即返回,預定的任務會完成但不會等它完成。因此,一個非同步函數不會阻塞當前線程去執行下一個函數。   (來源:http://www.cocoachina.com/industry/20140428/8248.html)  

  隊列分為串列和並行

  任務的執行分為同步和非同步

  -------  隊列只是負責任務的調度,而不負責任務的執行   ---------

  ------- 任務是線上程中執行的  ---------

  串列隊列:任務按照順序被調度,前一個任務不執行完畢,隊列不會調度

  並行隊列:只要有空閑的線程,隊列就會調度當前任務,交給線程去執行,不需要考慮前面是都有任務在執行,只要有線程可以利用,隊列就會調度任務。

  同步執行:不會開啟新的線程,任務按順序執行

  非同步執行:會開啟新的線程,任務可以併發的執行

  (來源:http://www.cnblogs.com/KongPro/p/5193175.html)

  【註:兩人說的有矛盾,一個說隊列執行任務,一個說隊列不執行任務= =一個說同步非同步是返回的問題,一個說同步非同步是開不開線程的問題】   同步(sync)非同步(async) 的主要區別在於會不會阻塞當前線程,直到 Block 中的任務執行完畢!
  如果是 同步(sync) 操作,它會阻塞當前線程並等待 Block 中的任務執行完畢,然後當前線程才會繼續往下運行。
  如果是 非同步(async)操作,當前線程會直接往下執行,它不會阻塞當前線程。   (原文鏈接:http://www.jianshu.com/p/0b0d9b1f1f19)   【第三個人和第一個人的意思差不多】

二、隊列

  GCD 提供有 dispatch queues 來處理代碼塊,這些隊列管理你提供給 GCD 的任務並用 FIFO 順序執行這些任務。這就保證了第一個被添加到隊列里的任務會是隊列中第一個開始的任務,而第二個被添加的任務將第二個開始,如此直到隊列的終點。

  1、串列隊列

    唯一能確保的事情是 GCD 一次只執行一個任務,並且按照我們添加到隊列的順序來執行。由於在串列隊列中不會有兩個任務併發運行。

  放到串列隊列的任務,GCD 會 FIFO(先進先出) 地取出來一個,執行一個,然後取下一個,這樣一個一個的執行。

  2、併發隊列

    在併發隊列中的任務能得到的保證是它們會按照被添加的順序開始執行,任務可能以任意順序完成,你不會知道何時開始運行下一個任務,或者任意時刻有多少 Block 在運行。再說一遍,這完全取決於 GCD 。

    放到並行隊列的任務,GCD 也會 FIFO的取出來,但不同的是,它取出來一個就會放到別的線程,然後再取出來一個又放到另一個的線程。這樣由於取的動作很快,忽略不計,看起來,所有的任務都是一起執行的。不過需要註意,GCD 會根據系統資源控制並行的數量,所以如果任務很多,它並不會讓所有任務同時執行。

    (來源:http://www.cocoachina.com/industry/20140428/8248.html)

  (原文鏈接:http://www.jianshu.com/p/0b0d9b1f1f19)

 

三、組合

  1. 串列隊列同步執行:綜合上面闡述的串列隊列的特點 --- 按順序執行,同步:不會開啟新的線程,則串列隊列同步執行只是按部就班的one by one執行。
  2. 串列隊列非同步執行:雖然隊列中存放的是非同步執行的任務,但是結合串列隊列的特點,前一個任務不執行完畢,隊列不會調度,所以串列隊列非同步執行也是one by one的執行
  1. 並行隊列同步執行:結合上面闡述的並行隊列的特點,和同步執行的特點,可以明確的分析出來,雖然並行隊列可以不需等待前一個任務執行完畢就可調度下一個任務,但是任務同步執行不會開啟新的線程,所以任務也是one by one的執行
  2. 並行隊列非同步執行:再上一條中說明瞭並行隊列的特點,而非同步執行是任務可以開啟新的線程,所以這中組合可以實現任務的併發,再實際開發中也是經常會用到的

  (來源:http://www.cnblogs.com/KongPro/p/5193175.html)

  【個人總結:串列並行區別就是有任務會不會放在別的線程

        同步非同步區別是會不會阻塞當前線程

        串列同步:取出一個任務不放進別的線程阻塞當前線程(不開闢新的線程)任務執行完畢任務執行完畢下一個任務

        串列非同步:取出一個任務不放進別的線程不阻塞當前線程不等任務執行完成任務執行完畢下一個任務

        並行同步:取出來一個任務可以放在別的線程阻塞當前線程(不開闢新的線程)任務執行完畢不等任務執行完畢下一個任務

        並行非同步:取出來一個任務可以放在別的線程不阻塞當前線程不等任務執行完成不等任務執行完成下一個任務

  】

  【所以現在最大的問題是,如果只有一個線程去非同步的執行一個並行隊列里的任務,會是怎樣?感覺上來說,不開線程的話就是同步,一旦叫非同步就說明開了線程,所以把這三個人的總結起來才比較合理

 

let queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL)  //創建串列隊列

   NSLog("之前 - %@", NSThread.currentThread())

    dispatch_async(queue, { () -> Void in      //非同步執行串列隊列-開了一個新的線程
        NSLog("sync之前 - %@", NSThread.currentThread())
        dispatch_sync(queue, { () -> Void in   //同步執行串列隊列-阻塞當前線程並等待上一個任務執行完畢(而上一個任務就是阻塞的這個)
             NSLog("sync - %@", NSThread.currentThread())
        })
        NSLog("sync之後 - %@", NSThread.currentThread())
   })

  NSLog("之後 - %@", NSThread.currentThread())

  【博客上找來的還是不放心,有時間在書上看到相關的我會再來更新】

--------------------------------------------------------------------------------

現在感覺,任務是先放在隊列里,從隊列里拿出來同步或者非同步執行,當然是不是這樣也有待考證。

如果是這樣的話,串列隊列只能一個一個拿出任務不管你是否阻塞原線程或者有沒有開闢新線程,任務都是一個一個執行。

並行隊列的話,如果是阻塞原線程的同步執行那也只能一個一個執行,如果是不阻塞原線程再開闢線程的話就可以一起執行了。

疑點在於

1、任務是不是先從隊列里拿出並按隊列的規則執行,尤其是串列非同步(會開闢新的線程麽?)和並行同步方面需要註意,他們之間的通信是怎麼實現的?

答:在GDC中一個操作是多線程執行還是單線程執行取決於當前隊列類型和執行方法,只有隊列類型為並行隊列並且使用非同步方法執行時才能在多個線程中執行。

2、雖然說同步非同步的區別在於是否阻塞原線程,但是除了開闢新的線程以外還有方法避免阻塞麽?那同步非同步的區別是不是就是有沒有開闢線程了?


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

-Advertisement-
Play Games
更多相關文章
  • html中的大部分的標簽都有一些糟糕的樣式,有的是標簽天然自帶的,有的是瀏覽器預設設置的,我們在寫網頁時,這些預設的樣式就會時不時的跳出來搗一下亂,搞得我們很是無奈。所以成手在寫css樣式時,一般都會在開頭寫一段初始化程式,來去掉這些預設樣式,比如最簡單的方法就是使用*{margin:0;paddi ...
  • 簡約版: 完整版: ...
  • 在項目中,由於實際描述文字過多,導致初始頁面縱向長度過長,也使得餘下信息利用率降低;所以在文字過多的時候,初始化限制行數是有必要的 1. CSS單行文本溢出,顯示省略號 2. CSS多行文本溢出,顯示省略號 上面兩種適合標簽裡面只有文字的情況,而有時我們會遇到這樣的情況 3. 第三種就是解決上面情況 ...
  • 創建非同步樹形菜單 <ul class="easyui-tree" id="treeMenu"> </ul> $(function(){ $('#treeMenu').tree({ url:'tree_data.json' //url的值是非同步獲取數據的頁面地址 }); }); $result = [ ...
  • 1.ele.getAttribute(attributeName); 返回元素的指定屬性值,如果元素沒有該屬性,則返回null 2.ele.setAttribute(attributeName,value); 為元素指定屬性設置值,如果沒有該屬性,則創建該屬性,並賦值 3.在IE 7以及更早版本部分 ...
  • ...
  • UEditor組件是百度提供的一套開源的web線上所見即所得富文本編輯器,具有輕量,可定製,註重用戶體驗等特點,基於MIT協議,功能很強大。最近在使用的過程中發現其中上傳的圖片(或者插入已有的表情包圖片)都無法正常縮放,選中圖片,用滑鼠點擊並拖動圖片邊沿的小標簽,圖片只能縮小不能放大。嘗試過很多方法 ...
  • 基本用法 先看一下最簡單的一個實現,代碼如下: 我們可以通過如下的方式來調用: 大家可能看到了,每次用的時候都要new一下,也就是說每個實例在記憶體里都是一份copy,如果你不需要傳參數或者沒有一些特殊苛刻的要求的話,我們可以在最後一個}後面加上一個括弧,來達到自執行的目的,這樣該實例在記憶體中只會存在 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...