線程
- 線程是進(jìn)程的基本執(zhí)行單元,一個(gè)進(jìn)程的所有任務(wù)都在線程中執(zhí)行。
- 程序啟動(dòng)會(huì)默認(rèn)開啟一條線程,被稱為主線程或UI線程。
進(jìn)程
- 進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序。
- 每個(gè)進(jìn)程之間是獨(dú)立的,每個(gè)進(jìn)程均運(yùn)行在其專用的且受保護(hù)的內(nèi)存中。
線程和進(jìn)程的關(guān)系
- 地址空間:同一進(jìn)程的線程共享本進(jìn)程的地址空間,而進(jìn)程之間則是獨(dú)立的地址空間。
- 資源擁有:同一進(jìn)程內(nèi)的線程共享本進(jìn)程的資源如內(nèi)存、I/O、CPU等,但是進(jìn)程之間的資源是獨(dú)立的。
- 一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其他進(jìn)程產(chǎn)生影響,但是一個(gè)線程崩潰整個(gè)進(jìn)程都死掉。所以多進(jìn)程比多線程健壯。
- 進(jìn)程切換時(shí),小號(hào)的資源大,效率高。所以設(shè)計(jì)到頻繁的切換時(shí),使用線程要好于進(jìn)程。同樣如果要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程不能用進(jìn)程。
- 執(zhí)行過程:每個(gè)獨(dú)立的進(jìn)程有一個(gè)程序運(yùn)行入口、順序執(zhí)行序列和程序入口。但是線程不能獨(dú)立運(yùn)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制。
- 線程是處理器調(diào)度的基本單元,但進(jìn)程不是。
多線程的意義
優(yōu)點(diǎn):
- 能適當(dāng)提高程序的執(zhí)行效率
- 能適當(dāng)提高資源的利用率(CPU、內(nèi)存)
- 線程上的任務(wù)執(zhí)行完成后,線程會(huì)自動(dòng)銷毀
缺點(diǎn):
- 開啟線程需要占用一定的內(nèi)存空間(默認(rèn)情況下,每一個(gè)線程都占512KB)如果開啟大量的線程,會(huì)占用大量的內(nèi)存空間,降低程序的性能
- 線程越多,CPU在調(diào)用線程上的開銷就越大
- 程序設(shè)計(jì)更加復(fù)雜,比如線程間的通信、多線程數(shù)據(jù)共享等
多線程的原理
CPU在單位時(shí)間片里快速在各個(gè)線程之間切換,以達(dá)到“并發(fā)”的效果

線程池的概念
當(dāng)我們新建一條線程NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];,在內(nèi)存中的表現(xiàn)為:

當(dāng)調(diào)用[thread start];后,系統(tǒng)把線程對(duì)象放入可調(diào)度線程池中,線程對(duì)象進(jìn)入就緒狀態(tài),如下圖所示:

當(dāng)然,可調(diào)度線程池中,會(huì)有其他的線程對(duì)象,如下圖所示。


多線程的生命周期

- 新建線程,調(diào)用start方法,進(jìn)入就緒狀態(tài)。
- 如果CPU調(diào)度當(dāng)前線程對(duì)象,則當(dāng)前線程對(duì)象進(jìn)入運(yùn)行狀態(tài),如果CPU調(diào)度其他線程對(duì)象,則當(dāng)前線程對(duì)象回到就緒狀態(tài)。
- 如果CPU在運(yùn)行當(dāng)前線程對(duì)象的時(shí)候調(diào)用了sleep方法\等待同步鎖,則當(dāng)前線程對(duì)象從可調(diào)度線程池移出,進(jìn)入了阻塞狀態(tài),等到sleep到時(shí)\得到同步鎖,則當(dāng)前線程重新添加回可調(diào)度線程池,回到就緒狀態(tài)。
- 如果CPU在運(yùn)行當(dāng)前線程對(duì)象的時(shí)候線程任務(wù)執(zhí)行完畢\異常強(qiáng)制退出,則當(dāng)前線程對(duì)象進(jìn)入死亡狀態(tài)。
多線程技術(shù)方案

多線程安全 - 鎖
線程與runloop的關(guān)系
1:runloop與線程是一一對(duì)應(yīng)的,一個(gè)runloop對(duì)應(yīng)一個(gè)核心的線程,為什么說是核心的,是因?yàn)閞unloop是可以嵌套的,但是核心的只能有一個(gè),它們的關(guān)系保存在一個(gè)全局的字典里。
2:runloop是來管理線程的,當(dāng)線程的runloop被開啟后,線程會(huì)在執(zhí)行完任務(wù)后進(jìn)入休眠狀態(tài),有了任務(wù)就會(huì)被喚醒去執(zhí)行任務(wù)。
3:runloop在第一次獲取時(shí)被創(chuàng)建,在線程結(jié)束時(shí)被銷毀。
4:對(duì)于主線程來說,runloop在程序一啟動(dòng)就默認(rèn)創(chuàng)建好了。
5:對(duì)于子線程來說,runloop是懶加載的,只有當(dāng)我們使用的時(shí)候才會(huì)創(chuàng)建,所以在子線程用定時(shí)器要注意:確保子線程的runloop被創(chuàng)建,不然定時(shí)器不會(huì)回調(diào)。