1.线程是什么,多线程是什么
当我写出代码,代码通过编译器转换为的CPU命令列(二进制代码).
int main{
id o = [[MyObject alloc init];
[o execBlock];
return 0;
}
OOOOOlac: b590 push (r4, r7, lr)
OOOOOlae: f240019c movw rl, :lowerl6:0x260-0xlc0+0xfffffffc
000001b2: afOl add r7, sp, #4
000001b4: f2c00100 movt rl, :upperl6:0x260-0xlc0+0xfffffffc
000001b8: f24010be movw r0, :lowerl6:0x384-0xlc2+0xfffffffc
OOOOOlbc: f2c00000 movt rO, :upperl6:0x384-0xlc2+0xfffffffc
OOOOOlcO: 4479 add rl, pc
000001c2: 4478 add r0, pc
000001c4: 6809 ldr rl, [rl, #0】
000001c6: 6800 ldr rO, [rO, #0]
000001c8: f7ffefla blx _obj c_msgSend
OOOOOlcc: f2400180 movw rlr :lowerl6:0x258-0xld4+0xfffffffc
OOOOOldO: f2c00100 movt rl, :upperl6:0x258-0xld4+0xfffffffc
000001d4: 4479 add rl, pc
000001d6: 6809 ldr rl, (rl, #0]
000001d8: f7ffefl2 blx _obj c_msgSend OOOOOldc: 4604 mov r4, rO
OOOOOlde: f240007a movw r0, :lowerl6:0x264-0xle6+0xfffffffc
000001e2: f2c00000 movt rO, :upperl6:0x264-0xle6+0xfffffffc
000001e6: 4478 add rO, pc
000001e8: 6801 Idr rl, [rO, *0J
OOOOOlea: 4620 mov rO, r4
OOOOOlec: f7ffef08 blx _objc_msgSend
OOOOOlfO: 4620 mov rO, r4
000001f2: f7ffef06 blx _objc_release
000001fe: 2000 movs rO, #0
000001f8: bd90 pop {r4, r7, pc)
以上的命令会在CPU上一个一个的依次的执行,不会出现两个命令在一个CPU上一起执行的场景
1.1 最初
定义1.0:「一个CPU执行的CPU命令列为一条无分叉路径----线程」
1.2 CPU相关科技发展,一个CPU有了多个核,真的多线程
定义2.0:「一个CPU核执行的CPU命令列为一条无分叉路径----线程」
一个多核CPU,每个核跑一个线程,自然有了多线程
1.3 CPU相关科技再发展,一个单核的CPU,也可以看起来像'多线程'
一个单核的CPU切割时间片段,
假设单位时间片段为1/60秒,
被开启线程有1号线程,2号线程,3号线程,也就是说在一秒内:
第一个1/60秒
在跑1号线程,
第二个1/60秒
在跑2号线程,
第三个1/60秒
在跑3号线程,
.....
如此循环往复也有了有了多线程
定义3.0:「一个CPU核同一时间内执行的CPU命令列为一条无分叉路径----线程」
1.4 上下文切换
换跑道:上下文切换
CPU核由路径1切换到路径2时,会将路径1在CPU寄存器上的信息全部清除.
问题来了,CPU再跑路径1时,怎么拿回这些数据呢?
老路径在CPU的寄存器的信息会保存到专有的内存块上.
新路径的在内存上的数据会被加载到CPU的寄存器上,
如此循环往复.
这就是传说中的----上下文切换
所以,使用太多线程会导致消耗大量内存
GCD(Grand Central Dispatch)属于系统级的线程管理
2 为什么要用多线程
app的主线程是用于更新UI,处理触摸屏幕的.
我们想象一个app内只有一个主线程,处理任务绝对按照1->2->3->4的来,
1:登录
2:网络请求
3:网络回调
4:登录成功跳转
因为只有一个主线程,step2+step3时,app无法更新UI(就连给个loading也做不了),出现假死.
而有了多线程
1:登录
2:网络请求 //次线程
3:网络回调 //次线程
4:登录成功跳转
step2+step3在次线程中做,主线程给出loading
网络回调后再通知主线程更新UI
多线程:卡谁都别卡主线程,因为主线程是要保证app如丝般润滑的.
多线程用自己的多维性
保证了主线程的绝对通畅,同时多线程也因为自己的多维无序性
带来了许多问题:
多线程的共同参与一份数据的读写一>大家都乱来一>数据竞争
线程等线程一>大家都不动手一>死锁
GCD就是来规避这些问题,更好管理线程的工具库
文章参考:
- Objective-C高级编程:iOS与OS X多线程和内存管理
- bestswifer iOS多线程编程——GCD与NSOperation总结
- 戴铭 细说GCD如何用