GCD相關

本文是自己寫的總結GCD的Demo的結果九孩。總結的過程中发框,參考了很多文章躺彬,文章底部有引用鏈接,在此感謝梅惯。
多圖宪拥,流量慎點??。

  • 概念介紹
  • 隊列的創(chuàng)建
  • 任務的創(chuàng)建與執(zhí)行
  • 實踐運用
  • 其他

概念介紹

進程和線程
進程(process):一個執(zhí)行中程序的實例铣减。指的是一個正在運行中的可執(zhí)行文件她君。每個進程都擁有獨立的虛擬內存空間和系統(tǒng)資源,包括端口權限等葫哗,而且至少包含一條主線程(或者可以包括任意數(shù)量的子線程)缔刹。當一個進程的主線程退出時,這個進程就結束了魄梯。對于iOS的app來說桨螺,一個app運行起來,就是一個進程酿秸。

進程.png

線程:(thread),指定是一個獨立的代碼執(zhí)行路徑灭翔,(代碼執(zhí)行的管道),線程是代碼執(zhí)行路徑的最小單位辣苏。

同步和異步
同步和異步操作的主要區(qū)別在于是否等待操作執(zhí)行完成肝箱,即是否阻塞當前線程。
同步:在發(fā)出一個同步調用時 稀蟋,在沒有得到結果之前煌张,該調用就不返回。
異步:在發(fā)出一個異步調用后退客,調用者不會立刻得到結果骏融,該調用就返回了链嘀。
同步和異步是針對能不能開線程。同步不能開啟新的線程档玻。異步可以怀泊。異步雖然有開啟新線程的能力,但不是說只要異步調用误趴,就開啟新線程了霹琼。
在iOS中,同步和異步即針對以下兩個函數(shù)凉当。

  • 同步函數(shù):
 dispatch_sync(queue, ^{
        
    })
  • 異步函數(shù):
 dispatch_async(queue, ^{
        
    })

串行和并發(fā)
串行和并發(fā)指的是任務(代碼)的執(zhí)行方式枣申。
串行是指多個任務時,各個任務按順序執(zhí)行看杭,挨個兒進行忠藤,完成一個之后才能進行下一個。順序不會亂楼雹。
并發(fā)指的是多個任務可以同時(一個時間段內)執(zhí)行熄驼。異步是并發(fā)的前提。
在iOS中烘豹,任務的執(zhí)行方式(串行或并發(fā)),由隊列來管理诺祸。隊列是用來存放任務的携悯。
隊列和線程
在iOS中,有兩種不同類型的隊列:串行隊列(主隊列是一種特殊的串行隊列)和并發(fā)隊列筷笨。串行隊列一次只能執(zhí)行一個任務憔鬼,并發(fā)隊列則可以允許多個任務同時執(zhí)行。iOS系統(tǒng)是使用這些隊列進行任務調度的 胃夏,系統(tǒng)會根據(jù)調度任務的需要和系統(tǒng)當前的負載情況動態(tài)的創(chuàng)建和銷毀線程轴或,不需要我們手動管理線程的銷毀。隊列負責任務的執(zhí)行方式仰禀;線程是任務的執(zhí)行通道照雁。

  • 串行隊列(Serial Dispatch Queue)
    每次只有一個任務被執(zhí)行。讓任務一個接著一個執(zhí)行答恶。
  • 并發(fā)隊列 (Concurrent Dispatch Queue)
    可以讓多個任務并發(fā)執(zhí)行饺蚊,在異步調用的前提下,可以開啟線程悬嗓,實現(xiàn)并發(fā)污呼。

插個題外話

并發(fā)和并行

  • 并發(fā)只是假象的同時,是單個處理器的計算機的cpu快速的在不同的程序上切換包竹。
  • 并行是真正意義上的同時燕酷,是多個處理器的計算機籍凝,各個cpu在同一時間執(zhí)行不同的程序。


    并發(fā)

    并行

    題外話插完了


隊列的創(chuàng)建

GCD中有三種隊列:串行隊列苗缩,并發(fā)隊列饵蒂,主隊列(一種特殊的串行隊列)。

//串行隊列創(chuàng)建

 dispatch_queue_t serialQueue = dispatch_queue_create("com.GCDDemo.testSerial", DISPATCH_QUEUE_SERIAL);

//并發(fā)隊列創(chuàng)建
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.GCDDemo.testConcurrent", DISPATCH_QUEUE_CONCURRENT);
創(chuàng)建隊列的函數(shù)有兩個參數(shù)挤渐,第一個參數(shù)表示隊列的標識符苹享,類似名字的作用,可為空浴麻。第二個參數(shù)表示隊列的種類得问,是串行隊列還是并發(fā)隊列,必填软免。
除了創(chuàng)建并發(fā)隊列外宫纬,還可以直接獲得系統(tǒng)為我們提供的全局并發(fā)隊列。

//獲取全局并發(fā)隊列
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
第一個參數(shù)表示隊列的優(yōu)先級膏萧,一般填默認的就可以漓骚。第二個參數(shù)是系統(tǒng)預留出來的,填0即可榛泛。

//獲取主隊列
dispatch_queue_t mainQueue = dispatch_get_main_queue();

任務的創(chuàng)建與執(zhí)行

//同步執(zhí)行任務創(chuàng)建
dispatch_sync(queue, ^{
    // 任務代碼
});

//異步函數(shù)執(zhí)行任務創(chuàng)建
 dispatch_async(queue, ^{
        //任務代碼
    });
上邊函數(shù)的block塊里是一個任務蝌蹂。

因為有兩種調用創(chuàng)建任務的函數(shù)和兩種隊列,再加上一種特殊的主隊列曹锨。所以我們就一共有六種情況孤个,不同的組合跑出來的效果不一樣,先看下這六種組合的區(qū)別沛简。

并發(fā)隊列 串行隊列 主隊列
同步 (sync) 沒有開啟新線程齐鲤,串行執(zhí)行任務 沒有開新線程,串行執(zhí)行任務 如果在主線程中調用:會出現(xiàn)死鎖椒楣,不執(zhí)行给郊。在其他線程中調用:沒有開新線程,串行執(zhí)行任務
異步(async) 會開啟新線程捧灰,并發(fā)執(zhí)行任務 會開啟一條新線程,串行執(zhí)行任務 沒有開啟新線程淆九,串行執(zhí)行任務

實踐運用

以下測試中所用到的并發(fā)隊列都用系統(tǒng)提供的全局并發(fā)隊列

  • 同步調用+并發(fā)隊列
    同步并發(fā)代碼.png
同步并發(fā)主.png

從運行結果中可以看出,同步函數(shù)調用凤壁,沒有開線程吩屹,任務都是在主線程進行,而且是順序串行執(zhí)行拧抖∶核眩【在主線程中運行該方法】

同步并發(fā)子.png

在子線程中運行的話,也一樣是沒有開新的線程唧席,所有任務都是按照順序串行執(zhí)行擦盾。

  • 同步調用+串行隊列
同步串行.png
同步串行主線程.png

主線程中: 同步串行嘲驾,沒有開啟新線程,所有任務都要按照屬性串行執(zhí)行迹卢,【當前同步函數(shù)的調用辽故,必須等到調用的函數(shù)執(zhí)行結束后(即需要將block塊里的任務執(zhí)行完),才能進行下一步】

同步串行子線程.png

子線程中腐碱,依然是沒有開啟新的線程誊垢。所有任務都是按照順序串行執(zhí)行。

  • 異步調用+并發(fā)隊列
    異步并發(fā)代碼.png
異步并發(fā)主.png

從運行結果來看症见,結束是先于函數(shù)調用block里的任務打印出來喂走,說明異步調用,不需要函數(shù)(dispatch_async)返回谋作,繼續(xù)往下執(zhí)行芋肠,從運行結果的線程number來看,開了三條子線程遵蚜,而且不同的任務分別在不同的線程中執(zhí)行帖池。說明異步并發(fā)開啟子線程。

異步并發(fā)子.png

在子線程中調用異步并發(fā)吭净,依然會開啟新的子線程睡汹。

  • 異步+串行隊列
異步串行代碼.png
異步串行主.png

異步串行在主線程中運行,開啟了一條新的線程執(zhí)行調用函數(shù)中加的任務寂殉。

異步串行子.png

在子線程中執(zhí)行方法帮孔,也會開一條新的子線程執(zhí)行函數(shù)調用中block中任務。

  • 同步調用+主隊列
同步主隊列 主線程.png

程序崩潰 主線程中的任務是在主隊列中的不撑,主隊列是串行隊列 ,任務需要一個個按照順序執(zhí)行晤斩。在主線程中調用了同步函數(shù)焕檬,這就相當于隊列中加了一個任務1,同步函數(shù)的block里又往主隊列里加了任務2澳泵。主隊列中的任務需要依次執(zhí)行实愚。所以任務2的執(zhí)行,需要任務1執(zhí)行完成(同步函數(shù)的調用返回)兔辅。但是任務1的調用返回必須得block塊里的代碼(即任務2)執(zhí)行完畢才可以腊敲。所以兩者相互等待,造成死鎖维苔∨龈ǎ【這里有點繞,不知道自己說的是否清楚??】

同步主隊列 子.png

如果再子線程里調用該方法介时,程序就能按照串行執(zhí)行没宾。不會崩潰凌彬。

由上可以得出死鎖發(fā)生的條件
1,隊列是串行隊列循衰。2铲敛,調用同步函數(shù)將任務加到自己的隊列中。

  • 異步調用+主隊列
    異步主隊列代碼.png
異步主隊列主.png

雖然是異步会钝,但是也沒有開啟子線程伐蒋,調用函數(shù)的任務都在主線程中執(zhí)行。

異步主隊列 子.png

在子線程中迁酸,也沒有開啟新的線程先鱼。

  • 線程間通信,從子線程回到主線程胁出。
    通信.png

    一般會在子線程做耗時工作型型,任務結束后,回到主線程更新UI全蝶。

其它方法

隊列組
隊列組通知代碼.png
隊列組通知結果.png
隊列組enter:leave代碼.png
隊列組enter:leave結果.png
隊列組wait代碼.png
隊列組wait結果.png

柵欄函數(shù)
柵欄代碼.png
柵欄結果.png

柵欄函數(shù)闹蒜,顧名思義,通過柵欄將上下的代碼隔開抑淫,真正的運行效果也是隔開了绷落。【我開發(fā)中沒有用到過這個函數(shù)始苇。不清楚用處】

延遲執(zhí)行
延遲執(zhí)行.png
一次執(zhí)行(單例)

說到單例砌烁,這里有篇談weak關鍵字的文章,延伸閱讀:弱引用單例

一次代碼.png

信號量

信號量
GCD中信號量有關的有三個函數(shù)催式。

//創(chuàng)建信號量 參數(shù):信號量的初始值函喉。
dispatch_semaphore_t  semaphore = dispatch_semaphore_create(0);
//將信號量減一  參數(shù):信號量,等待時間
// 等待降低信號量荣月,如果代碼執(zhí)行到這里管呵,信號量的值=0,則阻塞當前線程哺窄,知道信號量值大于0時捐下,才會進行執(zhí)行這里,同時將信號量減一萌业。
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//信號量加一坷襟。
dispatch_semaphore_signal(semaphore);
  • 1生年,線程同步

    信號量線程同步.png
    從圖中運行結果來看婴程,異步并發(fā)操作,調用異步函數(shù)時抱婉,應該不用等待該函數(shù)返回排抬,直接打印結束懂从。但是在這里加了信號量的控制。當走到dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);時蹲蒲,信號量為0番甩,此時線程阻塞,直到信號量大于0届搁;dispatch_semaphore_signal(semaphore)缘薛;當走到該行代碼時,信號量加1卡睦,信號量等待處開始執(zhí)行宴胧。

  • 2,控制最大并發(fā)數(shù)(這個需求用NSOperationQueue會更方便實現(xiàn)表锻。)

總結: 一直想把一些東西總結下來恕齐,有的時候看到了,覺得懂了瞬逊,但是到用的時候卻不是显歧。經過這次的總結,也發(fā)現(xiàn)了一些問題确镊,之后會陸續(xù)更新士骤。作為記錄,也希望能給需要的人以參考蕾域,如果有問題拷肌,歡迎指出。謝謝????旨巷。
最后巨缘,再次強調下:Demo傳送門 ????????歡迎star

參考:http://blog.csdn.net/sinat_35512245/article/details/53836580
http://www.reibang.com/p/2d57c72016c6
http://blog.csdn.net/fern_girl/article/details/61197995
http://www.cnblogs.com/kenshincui/p/3983982.html#3913461

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市采呐,隨后出現(xiàn)的幾起案子带猴,更是在濱河造成了極大的恐慌,老刑警劉巖懈万,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異靶病,居然都是意外死亡会通,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門娄周,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涕侈,“玉大人,你說我怎么就攤上這事煤辨∩烟危” “怎么了木张?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長端三。 經常有香客問我舷礼,道長,這世上最難降的妖魔是什么郊闯? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任妻献,我火速辦了婚禮,結果婚禮上团赁,老公的妹妹穿的比我還像新娘育拨。我一直安慰自己,他們只是感情好欢摄,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布熬丧。 她就那樣靜靜地躺著,像睡著了一般怀挠。 火紅的嫁衣襯著肌膚如雪析蝴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天唆香,我揣著相機與錄音嫌变,去河邊找鬼。 笑死躬它,一個胖子當著我的面吹牛腾啥,可吹牛的內容都是我干的。 我是一名探鬼主播冯吓,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼倘待,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了组贺?” 一聲冷哼從身側響起凸舵,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎失尖,沒想到半個月后啊奄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡掀潮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年菇夸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仪吧。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡庄新,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情择诈,我是刑警寧澤械蹋,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站羞芍,受9級特大地震影響哗戈,放射性物質發(fā)生泄漏。R本人自食惡果不足惜涩金,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一谱醇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧步做,春花似錦副渴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至将鸵,卻和暖如春勉盅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背顶掉。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工草娜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痒筒。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓宰闰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親簿透。 傳聞我的和親對象是個殘疾皇子移袍,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內容

  • 多線程學習筆記-GCD 我把這篇文章所用到的代碼總結到這里->GCD項目總結下載地址-GCD-wxk可以下載參考 ...
    wxkkkkk閱讀 536評論 0 2
  • 從哪說起呢? 單純講多線程編程真的不知道從哪下嘴老充。葡盗。 不如我直接引用一個最簡單的問題,以這個作為切入點好了 在ma...
    Mr_Baymax閱讀 2,762評論 1 17
  • 心有所想就有欲望啡浊,有欲望并不是壞事觅够。欲望過甚就會變苦,求不得苦從此而來巷嚣。然而這種時候其實就是你修行的時候喘先,有的時候...
    睡一夜就餿星人閱讀 383評論 0 1
  • 最近的生活充滿了刺激,總是忽然看到非常吸引的消息卻:1涂籽、過了申請的截止日期;2砸抛、即將過截止日期评雌;3树枫、懷著激動的心情...
    lxt閱讀 293評論 0 1
  • 感恩19大會議召開!各個行業(yè)景东,各個階層的人們都在慶祝19大砂轻,希望19大的召開能為人們帶來切實的利益,也希望我們的祖...
    武丹yoyo閱讀 359評論 0 2