iOS開發(fā)-多線程的一些基礎(chǔ)知識(shí)

多線程

首先介紹一下進(jìn)程和線程

進(jìn)程

  • 進(jìn)程代表當(dāng)前運(yùn)行的一個(gè)程序(是系統(tǒng)分配資源的基本單位,可以理解為一個(gè)工廠)
Paste_Image.psng

線程

  • 線程是cpu調(diào)度的最小單位,一個(gè)進(jìn)程含有一個(gè)線程或多個(gè)線程(應(yīng)用程序打開后會(huì)默認(rèn)開辟一個(gè)線程,叫做主線程或者UI線程,線程可以理解為工人里的一個(gè)工人

多線程的原理

  • 同一時(shí)間,CPU只能處理1條線程,只有1條線程在工作(執(zhí)行)
  • 多線程并發(fā)(同時(shí))執(zhí)行,其實(shí)是CPU快速地在多條線程之間調(diào)度(切換)
  • 如果CPU調(diào)度線程的時(shí)間足夠快,就造成了多線程并發(fā)執(zhí)行的
  • 創(chuàng)建的線程不易過多:
    CPU會(huì)在N多線程之間調(diào)度,CPU會(huì)累死,消耗大量的CPU資源
    每條線程被調(diào)度執(zhí)行的頻次會(huì)降低(線程的執(zhí)行效率降低)

多線程的缺點(diǎn)

  • 創(chuàng)建線程是有開銷的,iOS下主要成本包括:內(nèi)核數(shù)據(jù)結(jié)構(gòu)(大約1KB)、??臻g(子線程512KB、主線程1MB,也可以使用-setStackSize:設(shè)置,但必須是4K的倍數(shù),而且最小是16K),創(chuàng)建線程大約需要90毫秒的創(chuàng)建時(shí)間
  • 如果開啟大量的線程,會(huì)降低程序的性能
  • 線程越多,CPU在調(diào)度線程上的開銷就越大
  • 程序設(shè)計(jì)更加復(fù)雜:比如線程之間的通信、多線程的數(shù)據(jù)共享

主線程

  • 什么是主線程

    一個(gè)iOS程序運(yùn)行后,默認(rèn)會(huì)開啟1條線程,稱為“主線程”或“UI線程”

  • 主線程的主要作用

    顯示\刷新UI界面
    處理UI事件(比如點(diǎn)擊事件、滾動(dòng)事件、拖拽事件等)

  • 主線程的使用注意

    別將比較耗時(shí)的操作放到主線程中
    耗時(shí)操作會(huì)卡住主線程,嚴(yán)重影響UI的流暢度,給用戶一種“卡”的壞體驗(yàn)

串行-并行-并發(fā)區(qū)別

  • 串行:多個(gè)任務(wù)按順序執(zhí)行,類似于一個(gè)窗口辦公排隊(duì)

  • 執(zhí)行順序 下載文件A->下載文件B->下載文件C,也可以認(rèn)為線程是進(jìn)程中的一條文件路徑

  • 并行:多個(gè)任務(wù)同一時(shí)間一起執(zhí)行,類似于多個(gè)窗口辦公
  • 并發(fā):多個(gè)任務(wù)看似是同一時(shí)間一起執(zhí)行,但實(shí)際上是CPU快速的輪轉(zhuǎn)切換造成的假象


  • ps:我們使用多線程其實(shí)就是并發(fā)編程

使用多線程的優(yōu)點(diǎn):

  • 可以減少多個(gè)任務(wù)執(zhí)行所需要的總時(shí)長,提升cpu利用率

使用多線程的缺點(diǎn):

  • 1.線程需要耗費(fèi)系統(tǒng)資源 ,主線程要消耗??臻g的1MB資源,其他線程每個(gè)消耗512KB資源,不要過多使用
  • 2.線程使用過多會(huì)使程序變得復(fù)雜,容易出現(xiàn)問題,不容易調(diào)試維護(hù)

耗時(shí)操作建議放到子線程中(后臺(tái)線程,非子線程)

多線程實(shí)現(xiàn)方案

打印當(dāng)前線程

 NSLog(@"當(dāng)前線程 : %@",[NSThread currentThread]);

打印主線程

NSLog(@"主線程 : %@",[NSThread mainThread]);

判斷線程是否是主線程

BOOL isMainThread = [NSThread isMainThread];

休眠

[NSThread sleepForTimeInterval:3.0];

創(chuàng)建一個(gè)線程

    NSThread *thread  = [[NSThread alloc] initWithTarget:self selector:@selector(threadAction) object:nil];
    
//設(shè)置線程名    
thread.name = @"sq線程";

//設(shè)置線程優(yōu)先級(The thread’s priority, which is specified by a floating point number from 0.0 to 1.0, where 1.0 is highest priority.)
thread.threadPriority = 1.0f;

//需要手動(dòng)開啟線程
[thread start];

通過類方法創(chuàng)建一個(gè)線程(不推薦,設(shè)置不了相關(guān)屬性(如姓名等))

 [NSThread detachNewThreadSelector:@selector(threadAction) toTarget:self withObject:nil];

在后臺(tái)執(zhí)行一個(gè)方法(耗時(shí)操作)

 [self performSelectorInBackground:@selector(backgroundAction) withObject:nil];

在前臺(tái)執(zhí)行一個(gè)方法(如UI刷新操作需要在主線程中進(jìn)行)

 [self performSelectorOnMainThread:@selector(mainAction) withObject:nil waitUntilDone:YES];
 
     //參數(shù)1:需要在主線程中執(zhí)行的方法
    //參數(shù)2:傳值
    //參數(shù)3:是否阻塞線程(等待執(zhí)行完成后繼續(xù)執(zhí)行后面代碼)
 

A 線程鎖(比較耗資源,不建議用)

  • 在線程鎖中只有一個(gè)線程執(zhí)行完之后其他線程才能進(jìn)入
//通常用self作標(biāo)簽 
@synchronized (self) {}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容