多線程之 同步/異步/串行/并發(fā)

問題思考

  1. 什么是進(jìn)程、線程铲汪?線程和進(jìn)程的關(guān)系是什么掌腰?
  2. 線程和隊(duì)列的關(guān)系齿梁?
  3. 隊(duì)列有幾種勺择?
  4. 什么是同步、異步稿辙?什么是串行邻储、并行旧噪?
  5. 并行和并發(fā)有什么區(qū)別淘钟?
    看過這篇文章米母,這些有問題應(yīng)該就都有答案了铁瞒。

總是容易混淆這些概念,整理并記錄一下
目錄
1.先說幾個(gè)概念
2.隊(duì)列
串行燎斩、并發(fā)

先說幾個(gè)概念

  1. 進(jìn)程
  2. 線程
  3. 多線程
  4. 主線程

進(jìn)程在內(nèi)存中正在運(yùn)行的程序就是進(jìn)程,進(jìn)程是系統(tǒng)進(jìn)行資源調(diào)度分配的一個(gè)獨(dú)立單位蜂绎,進(jìn)程有獨(dú)立性栅表、并發(fā)性、動(dòng)態(tài)性师枣。
線程 線程是進(jìn)程的執(zhí)行單元怪瓶,是一個(gè)獨(dú)立的、并發(fā)的順序執(zhí)行流践美,進(jìn)程所有的任務(wù)都在線程中執(zhí)行洗贰。
多線程 在一個(gè)進(jìn)程中可以開辟多條線程,多條線程可以并發(fā)執(zhí)行不同的任務(wù)陨倡,多條線程并發(fā)執(zhí)行,其實(shí)是CPU 快速的在多條線程之間調(diào)度兴革,CPU 的執(zhí)行很快绎晃,調(diào)度的時(shí)間足夠快就會(huì)造成多線程同時(shí)執(zhí)行的假象。
主線程 一個(gè)iOS 程序運(yùn)行后杂曲,會(huì)默認(rèn)開啟一個(gè)線程庶艾,這個(gè)線程就是主線程,也叫UI線程
作用

  • 他可以通過RunLoop 來待續(xù)運(yùn)行和有事件觸發(fā)時(shí)及時(shí)喚醒響應(yīng)擎勘,沒有事件時(shí)就睡眠
  • 顯示/刷新UI界面
  • 處理UI事件

進(jìn)程和線程的關(guān)系 :線程是進(jìn)程的執(zhí)行單元咱揍,在進(jìn)程中開辟的獨(dú)立、并發(fā)的順序執(zhí)行流棚饵,進(jìn)程所有的任務(wù)都在線程中執(zhí)行煤裙。

隊(duì)列

FIFO (先進(jìn)先出),是一種數(shù)據(jù)結(jié)構(gòu)蟹地,用來存放任務(wù)

  • 隊(duì)列負(fù)責(zé)存放任務(wù)积暖、調(diào)度任務(wù),交給線程去執(zhí)行
  • 遵循FIFO (先進(jìn)先出)原則怪与,是指先調(diào)度夺刑,而不是先調(diào)度完成

串行、并發(fā)

串行和并發(fā)是指隊(duì)列的兩種類型分别。決定了任務(wù)的執(zhí)行順序

串行和并發(fā)隊(duì)列.png

*串行隊(duì)列遍愿,一次只能執(zhí)行一個(gè)任務(wù),上一個(gè)任務(wù)處理完成才能處理下一個(gè)任務(wù)耘斩;
*并發(fā)隊(duì)列沼填,多個(gè)任務(wù)可以同時(shí)執(zhí)行;處理順序還是先進(jìn)先出原則括授,但任務(wù)處理時(shí)間不同坞笙,有可能先進(jìn)后調(diào)度完成

并發(fā)在實(shí)際上岩饼,是處理器一下子處理任務(wù)A ,一下子處理任務(wù)B 薛夜,看起來就像同時(shí)在執(zhí)行多個(gè)任務(wù)

并行

并行和并發(fā)很容易讓人混淆
并行并發(fā)的效果在用戶看來是一樣的籍茧,但是其根本區(qū)別是有幾個(gè)CPU 在處理任務(wù)

  • 并行是真的有多個(gè)CPU 同時(shí)處理任務(wù)(多個(gè)線程在不同核上跑)
  • 并發(fā)是只有一個(gè)CPU ,單核高頻切換任務(wù)梯澜,使用戶覺得多個(gè)任務(wù)同時(shí)執(zhí)行
  • 并行是同一時(shí)間執(zhí)行多個(gè)任務(wù)
  • 并發(fā)是同一一時(shí)間間隔寞冯,執(zhí)行多個(gè)任務(wù)

任務(wù)

  • 任務(wù)就是 線程 要執(zhí)行的代碼
  • 執(zhí)行任務(wù)有兩種方式,同步異步

同步晚伙、異步

  1. 同步和異步代表任務(wù)的執(zhí)行方式
  • 同步執(zhí)行:當(dāng)前所在隊(duì)列會(huì)阻塞住吮龄,等待該任務(wù)執(zhí)行完成后恢復(fù);
    PS:這里涉及到兩個(gè)隊(duì)列咆疗,一個(gè)是當(dāng)前隊(duì)列漓帚,一個(gè)是任務(wù)所在隊(duì)列
    同步執(zhí)行會(huì)阻塞當(dāng)前隊(duì)列,同步執(zhí)行的任務(wù)完成之后午磁,當(dāng)前隊(duì)列才會(huì)恢復(fù)胰默。如果當(dāng)前隊(duì)列和任務(wù)所在隊(duì)列是同一個(gè),則會(huì)循環(huán)等待漓踢,造成死鎖牵署。
  • 異步執(zhí)行:當(dāng)前隊(duì)列不會(huì)阻塞,正常執(zhí)行任務(wù)

同步不會(huì)開辟新的線程喧半,異步可以開辟新的線程(不一定會(huì)開辟新線程)

串行/并發(fā)/同步/異步

串行隊(duì)列 并發(fā)隊(duì)列
同步執(zhí)行 串行執(zhí)行任務(wù) 串行執(zhí)行任務(wù)
異步執(zhí)行 串行執(zhí)行任務(wù) 并發(fā)執(zhí)行任務(wù)
  1. 串行隊(duì)列奴迅,同步執(zhí)行
    在當(dāng)前線程執(zhí)行,(不開啟新線程)并按順序一個(gè)一個(gè)執(zhí)行
  2. 串行隊(duì)列挺据,異步執(zhí)行
    線程由系統(tǒng)調(diào)度取具,(不一定會(huì)開啟新線程)按順序執(zhí)行
  3. 并發(fā)隊(duì)列,同步執(zhí)行
    在當(dāng)前線程執(zhí)行扁耐,(不開啟新線程)并按順序一個(gè)一個(gè)執(zhí)行 暇检;與串行、同步效果一樣
  4. 并發(fā)隊(duì)列婉称,異步執(zhí)行
    系統(tǒng)可以開啟新線程块仆,執(zhí)行順序不確定

主隊(duì)列

  • 主隊(duì)列的任務(wù)會(huì)在主線程執(zhí)行,主隊(duì)列是串行隊(duì)列王暗。
  • 在程序啟動(dòng)之后就已經(jīng)存在主線程和主隊(duì)列悔据,主隊(duì)列無需手動(dòng)創(chuàng)建,直接獲取俗壹。
  1. 主隊(duì)列科汗,異步執(zhí)行
 NSLog(@"1");
 dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"2");
    });
 NSLog(@"3");

結(jié)果:打印132。
解析:主線程異步執(zhí)行代碼绷雏,在主隊(duì)列里的任務(wù)執(zhí)行完成時(shí)头滔,該任務(wù)才會(huì)加到主隊(duì)列里怖亭,并執(zhí)行。

所以坤检,異步執(zhí)行不是一定會(huì)開啟線程依许。在主線程異步執(zhí)行主隊(duì)列任務(wù)時(shí),就不會(huì)開啟新線程缀蹄。

  1. 主隊(duì)列,同步執(zhí)行
 NSLog(@"1");
 dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"2");
    });
 NSLog(@"3");

結(jié)果:死鎖膘婶,系統(tǒng)崩潰

執(zhí)行順序 —————————————————-------———————>
主隊(duì)列: 任務(wù)1 |  同步任務(wù)塊 | 任務(wù)3 | 
                   ???? 
            |把任務(wù)2加到主隊(duì)列執(zhí)行|

解析:在主隊(duì)列里添加同步執(zhí)行的任務(wù)
由于是同步執(zhí)行缺前,在執(zhí)行同步任務(wù)時(shí),會(huì)阻塞當(dāng)前隊(duì)列悬襟。
該同步任務(wù)塊是把任務(wù)2添加到主隊(duì)列里執(zhí)行
而主隊(duì)列已經(jīng)被阻塞住 衅码,需要完成同步任務(wù)之后才會(huì)恢復(fù)。
所以循環(huán)等待導(dǎo)致死鎖脊岳,程序崩潰

全局隊(duì)列

  • 全局隊(duì)列本質(zhì)上是并發(fā)隊(duì)列逝段,是系統(tǒng)提供的開發(fā)者直接使用的并發(fā)隊(duì)列

代碼題

用幾個(gè)代碼題加深理解

  1. 輸出什么?
    1.1 隊(duì)列換成串行隊(duì)列呢割捅?
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    
    NSLog(@"1");
    dispatch_async(queue, ^{
        dispatch_sync(queue, ^{
            NSLog(@"%@", [NSThread currentThread]);
            NSLog(@"2");
        });
        
        NSLog(@"%@", [NSThread currentThread]);
        NSLog(@"3");
        
        dispatch_async(queue, ^{
            NSLog(@"%@", [NSThread currentThread]);
            NSLog(@"4");
        });
        NSLog(@"5");
    });
    NSLog(@"6");

1) 打印162354 奶躯,線程打印不一定,因?yàn)槭遣l(fā)隊(duì)列
1.1) 打印16亿驾, 崩潰 嘹黔。串行隊(duì)列,同步執(zhí)行任務(wù)莫瞬,相互等待死鎖

  1. 打印順序
    2.1 改為串行隊(duì)列呢儡蔓?
 dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"1");
    });
    dispatch_async(queue, ^{
        NSLog(@"2");
    });
    dispatch_sync(queue, ^{
        NSLog(@"3");
    });
    NSLog(@"0");
    
    dispatch_async(queue, ^{
        NSLog(@"4");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"7");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"8");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"9");
    });

2)答 :1,2,4,7,8,9 由于是異步執(zhí)行,開啟新線程疼邀,所以順序不能確定; 3 是同步執(zhí)行喂江,與0 同在主線程,所以3在0前面旁振; 主線程任務(wù)是順序添加的获询,所以0在789 前面
2.1)順序打印1230789

  1. 輸出什么
    3.1 塊任務(wù)中NSLog(@"3");,改為同步任務(wù)拐袜,輸出什么
 dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(queue, ^{
        NSLog(@"1");
    });
    dispatch_async(queue, ^{
        NSLog(@"2");
        dispatch_async(queue, ^{
            NSLog(@"3");
        });
        NSLog(@"4");
    });
    dispatch_sync(queue, ^{
        NSLog(@"5");
    });

3)15243
3.1)15234

  1. 輸出什么
    4.1 如果把全局并發(fā)隊(duì)列換成 創(chuàng)建的queue 怎么打印
 dispatch_queue_t queue = dispatch_queue_create("test",  DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
        NSLog(@"1");
    });
    dispatch_async(queue, ^{
        NSLog(@"2");
        dispatch_sync(dispatch_get_global_queue(0,0), ^{
            NSLog(@"3");
        });
        NSLog(@"4");
    });
    dispatch_sync(queue, ^{
        NSLog(@"5");
    });

4)15234
4.1)152崩潰

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末筐付,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子阻肿,更是在濱河造成了極大的恐慌瓦戚,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丛塌,死亡現(xiàn)場離奇詭異较解,居然都是意外死亡畜疾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門印衔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啡捶,“玉大人,你說我怎么就攤上這事奸焙∠故睿” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵与帆,是天一觀的道長了赌。 經(jīng)常有香客問我,道長玄糟,這世上最難降的妖魔是什么勿她? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮阵翎,結(jié)果婚禮上逢并,老公的妹妹穿的比我還像新娘。我一直安慰自己郭卫,他們只是感情好砍聊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著贰军,像睡著了一般辩恼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谓形,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天灶伊,我揣著相機(jī)與錄音,去河邊找鬼寒跳。 笑死聘萨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的童太。 我是一名探鬼主播米辐,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼书释!你這毒婦竟也來了翘贮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤爆惧,失蹤者是張志新(化名)和其女友劉穎狸页,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芍耘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年址遇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斋竞。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡倔约,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坝初,到底是詐尸還是另有隱情浸剩,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布鳄袍,位于F島的核電站绢要,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏畦木。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一砸泛、第九天 我趴在偏房一處隱蔽的房頂上張望十籍。 院中可真熱鬧,春花似錦唇礁、人聲如沸勾栗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽围俘。三九已至,卻和暖如春琢融,著一層夾襖步出監(jiān)牢的瞬間界牡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國打工漾抬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宿亡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓纳令,卻偏偏與公主長得像挽荠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子平绩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容