这是我参与 8 月更文挑战的第 2 天,活动详情查看: 8月更文挑战
线程安全
- 概念
- 死锁
- 临界区
- 竟态条件
- 两个或多个线程读写某些共享数据,而最后的结果取决于线程运行的精确时序
- 优先级反转
- 并发和并行
- 锁
- 自旋锁, SpinLock
- 线程通过busy-wait-loop的方式来获取锁,任时刻只有一个线程能够获得锁,其他线程忙等待知道获得锁
- 临界区尽量短,控制100行之内,不要有显式或隐式的系统调用,调用的函数也尽量简短。
- 保证访问锁的线程都处于同一优先级
bool lock = false; do { while(test_and_set(&lock)); // test_and_set 是原子操作 Critical section // 临界区 lock = false;// 释放锁 Remider section // 不需要保护的代码 }- synchronized
- 只有传同样的对象给synchronized,才能起到加锁的作用
- 如果传nil, 是无法起到加锁的作用
- 可以重入
- synchronized 不会持有传给它的对象
- SyncData
func synchronized(_ obj: AnyObject, clousure:()->() { objc_sync_enter(obj) closure() objc_sync_exit(obj) } - 自旋锁, SpinLock
场景
需求
- 一个页面有三个网络请求,需要三个网路请求都返回的时候刷新页面
- 实现一个线程安全的Array的读和写
- 编写一个多线程下载器,可以执行多个下载任务,每个任务可以保存下下载字节数,总字节数,可以设置回调得到当前下载进度
- 需要在主线程等待一个异步任务返回,才能继续执行下面的逻辑,但是又不希望堵塞用户事件
其他模式
- Promise
- Pipeline
- Master-Slave
- Serial Thread Confinment