iOS多線程-全面總結(jié)

iOS多線程-全面總結(jié)


  • 進(jìn)程和線程

進(jìn)程:

進(jìn)程(Process)是計(jì)算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動(dòng)尘分,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位衩椒,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)(百度百科)

根據(jù)百度百科的解釋我們知道進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位教届,在手機(jī)端一個(gè)進(jìn)程就是一個(gè)app

線程:

線程茎截,有時(shí)被稱為輕量級進(jìn)程(Lightweight Process知牌,LWP)丹拯,是程序執(zhí)行流的最小單元站超。一個(gè)標(biāo)準(zhǔn)的線程由線程ID,當(dāng)前指令指針(PC)乖酬,寄存器集合和堆棧組成死相。(百度百科)

根據(jù)百度百科我們知道,線程來說其實(shí)是進(jìn)程一個(gè)實(shí)體

一個(gè)進(jìn)程中至少有一條線程咬像,這條線程我們稱為主線程

  • iOS中的創(chuàng)建線程和操作線程
  • pThread:純c語言編寫,需要自己管理線程的聲明周期

OS X and iOS provide C-based support for creating threads using the POSIX thread API. This technology can actually be used in any type of application (including Cocoa and Cocoa Touch applications) and might be more convenient if you are writing your software for multiple platforms. The POSIX routine you use to create threads is called, appropriately enough, pthread_create.(蘋果官方文檔)

官方文檔上說算撮,這是一個(gè)基于C語言的創(chuàng)建和使用線程的API,而且是一個(gè)跨平臺(tái)的API县昂。查看官方文檔https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/10000057i-CH15-SW12

  • NSThread:OC封裝面向?qū)ο蟀构瘢枰约汗芾砭€程釋放,相對用起來比較簡單
四種創(chuàng)建方式:
// 1.需要調(diào)用start倒彰,才會(huì)去創(chuàng)建線程加入到當(dāng)前隊(duì)列
NSThread *t = [[NSThread alloc] initWithTarget:self selector:@selector(task) object:nil];

// 2.iOS10新加入的方法审洞,同上
 NSThread *thread = [[NSThread alloc] initWithBlock:^{

    }];
 [myThread start];  // Actually create the thread
 // 3.detach 直接創(chuàng)建線程,加入當(dāng)前隊(duì)列
 [NSThread detachNewThreadWithBlock:^{
        [self task];
    }]; //@available iOS10
  // 4.同上
  [NSThread detachNewThreadSelector:@selector(task) toTarget:self withObject:nil];

還有一些實(shí)用的熟悉和方法比如
currentThread待讳、isMultiThreaded芒澜、
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
+ (void)exit; 等等如果查看NSThread.h文件

pThread缩赛、NSThread 都需要我們自己去創(chuàng)建管理線程的聲明周期,所以之后出現(xiàn)了不要我們管理線程的生命周期的 GCD撰糠、NSOpration酥馍。


  • GCD:API基于C語言, 我們需要關(guān)心的概念是隊(duì)列、任務(wù)阅酪,不在需要管理線程問題旨袒,CGD自動(dòng)創(chuàng)建、分配术辐、管理線程砚尽。

下面我們通過具體的代碼例子,引出結(jié)論和理解:

  1. 同步隊(duì)列
    NSLog(@"當(dāng)前線程:%@", [NSThread currentThread]);
    
    dispatch_queue_t testQueue = dispatch_queue_create("com.haoyuhong.testQueue", NULL);
    
    /// 同步執(zhí)行辉词, 當(dāng)前主線程串行執(zhí)行
    dispatch_sync(testQueue, ^{
        NSLog(@"2. 當(dāng)前線程: %@", [NSThread currentThread]);
    });
    
    /// 異步執(zhí)行必孤, 分配新線程執(zhí)行
    dispatch_async(testQueue, ^{
        NSLog(@"3. 當(dāng)前線程: %@", [NSThread currentThread]);
    });
    
    /// 異步執(zhí)行,在已經(jīng)分配的線程串行執(zhí)行
    dispatch_async(testQueue, ^{
        NSLog(@"4. 當(dāng)前線程: %@", [NSThread currentThread]);
    });
 
輸出結(jié)果
當(dāng)前線程:<NSThread: 0x600002899240>{number = 1, name = main}
2019-09-03 15:50:48.125511+0800 TestGCD[95991:16450263] 2. 當(dāng)前線程: <NSThread: 0x600002899240>{number = 1, name = main}
2019-09-03 15:50:48.125671+0800 TestGCD[95991:16450326] 3. 當(dāng)前線程: <NSThread: 0x6000028c1b40>{number = 3, name = (null)}
2019-09-03 15:50:48.125765+0800 TestGCD[95991:16450326] 4. 當(dāng)前線程: <NSThread: 0x6000028c1b40>{number = 3, name = (null)}
我們得出以下結(jié)論:
* 串行隊(duì)列總結(jié): 串行隊(duì)列瑞躺,特點(diǎn):保證順序執(zhí)行敷搪。
1. 如若同步執(zhí)行,不分配線程幢哨,在當(dāng)前線程串行執(zhí)行赡勘;
2. 如若,異步執(zhí)行捞镰,不阻塞當(dāng)前線程闸与,如果沒有開辟新線程則開辟新線程,如果已經(jīng)開辟了一條線程岸售,則任務(wù)會(huì)在開辟的線程中串行執(zhí)行践樱,保持順序執(zhí)行。
死鎖: 造成死鎖的原因就是:相互等待凸丸,串行隊(duì)列的特點(diǎn)就是順序執(zhí)行拷邢,如果同步執(zhí)行任務(wù)在當(dāng)前串行隊(duì)列中執(zhí)行,就會(huì)造成死鎖甲雅。
  1. 并發(fā)隊(duì)列
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.haoyuhong.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    
    /// 并發(fā)隊(duì)列解孙,同步任務(wù),不分配線程抛人,在當(dāng)前線程執(zhí)行
    dispatch_sync(concurrentQueue, ^{
       NSLog(@"1. 當(dāng)前線程: %@", [NSThread currentThread]);
    });
    
    /// 并發(fā)隊(duì)列弛姜,異步任務(wù),分配線程妖枚,并發(fā)執(zhí)行
    dispatch_async(concurrentQueue, ^{
        NSLog(@"2. 當(dāng)前線程: %@", [NSThread currentThread]);
    });
    
    /// 并發(fā)隊(duì)列廷臼,異步任務(wù),分配線程,并發(fā)執(zhí)行
    dispatch_async(concurrentQueue, ^{
        NSLog(@"3. 當(dāng)前線程: %@", [NSThread currentThread]);
    });
## 輸出結(jié)果
2019-09-03 15:50:48.126185+0800 TestGCD[95991:16450263] 1. 當(dāng)前線程: <NSThread: 0x600002899240>{number = 1, name = main}
2019-09-03 15:50:48.126313+0800 TestGCD[95991:16450326] 2. 當(dāng)前線程: <NSThread: 0x6000028c1b40>{number = 3, name = (null)}
2019-09-03 15:50:48.126345+0800 TestGCD[95991:16450325] 3. 當(dāng)前線程: <NSThread: 0x6000028d1b80>{number = 5, name = (null)}
總結(jié)如下
并發(fā)隊(duì)列荠商, 特點(diǎn):并發(fā)執(zhí)行
1. 同步任務(wù)寂恬,隊(duì)列不會(huì)分配新線程去執(zhí)行,在當(dāng)前線程串行執(zhí)行
2. 異步任務(wù)莱没,隊(duì)列分配新線程初肉,所有異步任務(wù),并發(fā)執(zhí)行
  • 系統(tǒng)隊(duì)列:

    1. 主隊(duì)列
      串行隊(duì)列饰躲,不管是同步還是異步牙咏,都不會(huì)創(chuàng)建新線程,所有任務(wù)都是在主線程執(zhí)行嘹裂,所以他是一種特殊的串行隊(duì)列妄壶。如果當(dāng)前執(zhí)行線程為主線程,添加同步任務(wù)會(huì)造成寄狼,互相等待狀態(tài)丁寄,導(dǎo)致死鎖;異步執(zhí)行泊愧,等待主線程此異步任務(wù)之前所有任務(wù)執(zhí)行完畢執(zhí)行伊磺。
      獲取函數(shù):dispatch_get_main_queue()
    2. 全局隊(duì)列
      并發(fā)隊(duì)列。
      獲取函數(shù):dispatch_get_global_queue(0, 0)
      第一個(gè)參數(shù)拼卵,服務(wù)質(zhì)量決定任務(wù)執(zhí)行的優(yōu)先級
      The quality of service you want to give to tasks executed using this queue. Quality-of-service helps determine the priority given to tasks executed by the queue.QOS_CLASS_USER_INTERACTIVE, QOS_CLASS_USER_INITIATED, QOS_CLASS_UTILITY, or QOS_CLASS_BACKGROUND
  • DispatchGroup
    dispatch_group: 將隊(duì)列添加到隊(duì)列組里
    隊(duì)列組可以添加一個(gè)任務(wù)到隊(duì)列并且將隊(duì)列加入隊(duì)列組

    • dispatch_group_create() /// 創(chuàng)建分發(fā)組

    • dispatch_group_async(dispatch_group_t group,
      dispatch_queue_t queue,
      dispatch_block_t block); /// 添加block任務(wù)到隊(duì)列奢浑,并且關(guān)聯(lián)到分發(fā)組

    • void
      dispatch_group_notify(dispatch_group_t group,
      dispatch_queue_t queue,
      dispatch_block_t block); /// 監(jiān)聽所有隊(duì)列里的任務(wù)都完成后執(zhí)行block里的任務(wù)

    • dispatch_group_wait(group, DISPATCH_TIME_FOREVER); /// 同步等待所有之前加入的任務(wù)都執(zhí)行完畢

  • 柵欄函數(shù)
    柵欄函數(shù):保證之前加入的任務(wù)都執(zhí)行完畢,之后加入的任務(wù)等待柵欄任務(wù)執(zhí)行完畢腋腮。

    • dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
    • void
      dispatch_barrier_sync(dispatch_queue_t queue,
      DISPATCH_NOESCAPE dispatch_block_t block);
      void
  • 延遲執(zhí)行:

    • dispatch_after(dispatch_time_t when,
      dispatch_queue_t queue,
      dispatch_block_t block);
  • 執(zhí)行一次函數(shù):應(yīng)用于單利的創(chuàng)建

    • dispatch_once(dispatch_once_t *predicate,
      DISPATCH_NOESCAPE dispatch_block_t block);

  • NSOperation
    NSOperation 是一個(gè)抽象任務(wù)類,不能直接使用壤蚜,需要實(shí)例化兩個(gè)子類使用即寡,基于GCD的封裝,將多線程簡單化為隊(duì)列和任務(wù)袜刷,使用起來也是很簡單的
    *它與CGD的區(qū)別就是GCD是更底層的封裝聪富,在性能上會(huì)比NSOperation好點(diǎn)

    • NSBlockOperation:用一個(gè)block的方式初始化一個(gè)任務(wù)
      實(shí)例化:
      NSBlockOperation *task1 = [NSBlockOperation blockOperationWithBlock:^{
      NSLog(@”1-%@”, [NSThread currentThread]);
      }];

    • NSInvocationOperation:Target-Action的方式初始一個(gè)任務(wù)
      初始化方式:
      NSInvocationOperation *task2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task) object:nil];

    • NSOperationQueue :任務(wù)運(yùn)行隊(duì)列
      init方式初始:初始化一個(gè)并行隊(duì)列
      NSOperationQueue *queue = [[NSOperationQueue alloc] init];
      mianQueue方式獲取主隊(duì)列:獲取主隊(duì)列,是一個(gè)串行隊(duì)列
      NSOperationQueue *queue = [NSOperationQueue mainQueue];

      • 直接添加任務(wù)block到隊(duì)列
        – (void)addOperationWithBlock:(void (^)(void))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
      • 設(shè)置并發(fā)數(shù):maxConcurrentOperationCount
      • 掛起當(dāng)前隊(duì)列:suspended
      • 設(shè)置隊(duì)列的優(yōu)先級:qualityOfService
      • 取消隊(duì)列所有任務(wù): cancelAllOperations
      • 等待所有隊(duì)列任務(wù)執(zhí)行完成:
        – (void)waitUntilAllOperationsAreFinished;
    • 添加任務(wù)依賴:一個(gè)任務(wù)需要依賴另外一個(gè)任務(wù)執(zhí)行完成才能執(zhí)行
      – (void)addDependency:(NSOperation *)op;
      *移除依賴關(guān)系:
      – (void)removeDependency:(NSOperation *)op;

以上iOS多線程中知識(shí)著蟹,在此做一個(gè)總結(jié)墩蔓,一起共勉!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末萧豆,一起剝皮案震驚了整個(gè)濱河市奸披,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涮雷,老刑警劉巖阵面,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡样刷,警方通過查閱死者的電腦和手機(jī)仑扑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來置鼻,“玉大人镇饮,你說我怎么就攤上這事』福” “怎么了盒让?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長司蔬。 經(jīng)常有香客問我邑茄,道長,這世上最難降的妖魔是什么俊啼? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任肺缕,我火速辦了婚禮,結(jié)果婚禮上授帕,老公的妹妹穿的比我還像新娘同木。我一直安慰自己,他們只是感情好跛十,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布彤路。 她就那樣靜靜地躺著,像睡著了一般芥映。 火紅的嫁衣襯著肌膚如雪洲尊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天奈偏,我揣著相機(jī)與錄音坞嘀,去河邊找鬼。 笑死惊来,一個(gè)胖子當(dāng)著我的面吹牛丽涩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裁蚁,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼矢渊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了枉证?” 一聲冷哼從身側(cè)響起矮男,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刽严,沒想到半個(gè)月后昂灵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體避凝,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年眨补,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了管削。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡撑螺,死狀恐怖含思,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情甘晤,我是刑警寧澤含潘,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站线婚,受9級特大地震影響遏弱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜塞弊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一漱逸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧游沿,春花似錦饰抒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至眯勾,卻和暖如春枣宫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背咒精。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工镶柱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人模叙。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像鞋屈,于是被迫代替她去往敵國和親范咨。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

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

  • 背景 擔(dān)心了兩周的我終于輪到去醫(yī)院做胃鏡檢查了厂庇!去的時(shí)候我都想好了最壞的可能(胃癌)渠啊,之前在網(wǎng)上查的癥狀都很相似。...
    Dely閱讀 9,237評論 21 42
  • NSThread 第一種:通過NSThread的對象方法 NSThread *thread = [[NSThrea...
    攻城獅GG閱讀 797評論 0 3
  • 歡迎大家指出文章中需要改正或者需要補(bǔ)充的地方权旷,我會(huì)及時(shí)更新替蛉,非常感謝。 一. 多線程基礎(chǔ) 1. 進(jìn)程 進(jìn)程是指在系...
    xx_cc閱讀 7,185評論 11 70
  • GCD (Grand Central Dispatch) :iOS4 開始引入,使用更加方便躲查,程序員只需要將任務(wù)添...
    池鵬程閱讀 1,332評論 0 2
  • RN 第三方庫快速查找網(wǎng)址:https://js.coach/ (下面的文章以https://github.com...
    Tmac50閱讀 16,799評論 3 10