一、進(jìn)程和線程
-
什么是進(jìn)程?
- 一個應(yīng)用程序啟動后,系統(tǒng)會先啟動一個進(jìn)程,放入內(nèi)存中運(yùn)行.
- 也就是說進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個應(yīng)用程序運(yùn)行實(shí)例,一個應(yīng)用程序是可以多開的.所以說一個應(yīng)用程序可以對應(yīng)多個進(jìn)程.(可以把應(yīng)用程序看成是一個類,而進(jìn)程就是類的實(shí)例)
-
每個進(jìn)程都是獨(dú)立的, 運(yùn)行在其專用并受保護(hù)的內(nèi)存內(nèi).
76B8F2D4-C7FC-4C11-BFE6-E58258D262DC.png - 如上圖,同時打開了QQ(登陸了兩個Q),快播,Xcode,系統(tǒng)就會分別開啟4個進(jìn)程
-
什么是線程?
- 進(jìn)程本身是不能執(zhí)行任務(wù)的,進(jìn)程想要執(zhí)行任務(wù)必須的有線程,只有線程才能執(zhí)行任務(wù),所以在進(jìn)程啟動運(yùn)行的時候會創(chuàng)建一條默認(rèn)的線程(
主線程) -
一個進(jìn)程中可以有多條線程(一條主線程多條子線程),線程是CPU執(zhí)行任務(wù)的基本單位,進(jìn)程的所有任務(wù)都是在線程中執(zhí)行的.
5A4FE897-4BFE-48CE-9117-B39002577E9D.png -
線程是串行(一個一個的執(zhí)行)執(zhí)行任務(wù)的,也就是說線程在同一時間內(nèi)只能執(zhí)行一個任務(wù),處理完之后才能處理下一個任務(wù)
A0BFEB30-E8E3-42C3-9E8E-6DD0B0C10542.png
- 進(jìn)程本身是不能執(zhí)行任務(wù)的,進(jìn)程想要執(zhí)行任務(wù)必須的有線程,只有線程才能執(zhí)行任務(wù),所以在進(jìn)程啟動運(yùn)行的時候會創(chuàng)建一條默認(rèn)的線程(
二、多線程
-
什么是多線程?
- 多線程,顧名思義多條線程.
-
如上面所說一條線程在同一時間內(nèi)只能執(zhí)行一個任務(wù),但是進(jìn)程可以有多條線程.那我們不就可以開啟多條線程來執(zhí)行不同的任務(wù),從而提高程序的執(zhí)行效率. 如下圖:
E1371E01-DD57-4146-A276-CFCC5057B6D6.png
-
多線程執(zhí)行原理
- 同一時間內(nèi),CPU只能處理一條線程,只有一條線程在工作.
- 多線程并行執(zhí)行,其實(shí)就是CPU在不同線程之間快速的調(diào)度,從而導(dǎo)致假象并行執(zhí)行.
-
多線程優(yōu)點(diǎn)
- 可以適當(dāng)提高程序執(zhí)行效率
- 能適當(dāng)提高資源利用率(CPU,內(nèi)存)
-
多線程的缺點(diǎn)
-
創(chuàng)建線程是有開銷的,在IOS中主要成本包括:
- 線程的創(chuàng)建時間大概是90毫秒
- 內(nèi)核數(shù)據(jù)結(jié)構(gòu)(大概1KB)
- 棧空間
- 主線程1MB
- 子線程512KB
- 也可以使用
-setStackSize來設(shè)置線程??臻g的大小,但必須是4的倍數(shù),最低16K
-
如果開啟大量線程的話,會適得其反減低程序性能
- 占用大量的內(nèi)存,導(dǎo)致程序性能降低
- 線程一多的話,CPU在線程之間的調(diào)度上開銷就越大
- 每條線程的調(diào)度次數(shù)會降低
-
線程一多會讓程序設(shè)計(jì)會變得更加復(fù)雜,比如(線程之間的通信,多線程之間的數(shù)據(jù)共享)
-
進(jìn)程和線程的比較
- 1.線程是CPU執(zhí)行任務(wù)的基本單位
- 2.進(jìn)程是CPU分配資源單位
- 3.一個程序可以對應(yīng)多個進(jìn)程,一個進(jìn)程可以有多條線程,但至少有一個線程
- 4.同一個進(jìn)程內(nèi)的線程共享進(jìn)程里的資源
-
三、多線程在ios里的應(yīng)用
-
程序在啟動之后,會默認(rèn)創(chuàng)建一條線程,稱為
主線程或UI線程 -
作用
- 顯示和刷新UI界面用途
- 處理UI事件
-
除了主線程之外的線程就是子線程,也叫做后臺線程,子線程不能用來刷新UI
-
多線程使用注意
- 和UI相關(guān)的刷新操作必須放到主線程中進(jìn)行處理
- 別將耗時的操作放入主線程內(nèi)
- 耗時操作會將主線程阻塞,無法處理用戶產(chǎn)生的事件,會給用戶一種卡頓的感覺
四、阻塞線程示例
//
// ViewController.m
//
// Created by 雨軒 16/1/22.
// Copyright ? 2016年 apple. All rights reserved.
//
#import "ViewController.h"
#import <pthread.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//獲取當(dāng)前線程 ,后面我專門會寫一篇關(guān)于NSThread的文章
NSThread * thread = [NSThread currentThread];
for(int i = 0 ; i < 99999; i++){
NSLog(@"%d======%@",i,thread);
}
}
@end

Paste_Image.png
-
示例說明:
- 程序啟動后,點(diǎn)擊屏幕,開始執(zhí)行循環(huán)
- 然后點(diǎn)擊開關(guān),和滾動文本,會發(fā)現(xiàn)開關(guān)不能動,文本不能滾動
- 原因 : 前面說過一條線程在同一時間內(nèi)只能執(zhí)行一個任務(wù),但是當(dāng)前主線程一直在執(zhí)行循環(huán)從而被阻塞了,所以點(diǎn)擊開關(guān)事件和文本滾動事件無法被響應(yīng).(這個時候我們就得用到多線程技術(shù)了,把耗時操作放入子線程中.)



