1. 自旋锁 spinlock/cas
当访问另一个线程锁定的部分时忙等待,一直占用CPU资源, 当锁定部分的代码执行很快时适合用自旋锁.
2. 互斥锁 os_unfair_lock/pthread_mutex/NSLock
没有获取到锁时会让当前线程进入休眠状态.
NSLock
封装了pthread_mutex的PTHREAD_MUTEX_NORMAL
模式NSRecursiveLock
封装了pthread_mutex的PTHREAD_MUTEX_RECURSIVE
模式
3. 递归锁
同一线程访问一段代码,如果是加锁的可以继续加锁.不同线程发现有锁要等待所有锁解开之后才可以继续执行
4. 条件锁
一定条件下,让其等待休眠并放开锁,等接收到信号或者广播,会从新唤起线程,并重新加锁.
NSCondition
支持lock/unlock/wait阻塞/signal唤醒操作.是对pthread_cond_wait
,pthread_cond_signal
,pthread_cond_broadcast
的包装. NSConditionLock
封装了NSCondition
,不需要wait/signal,接受条件(int值),例:
//produce
dispatch_exe(produce_thread){
while(true){
condition.lock
if(full){ ondition.wait //block}
// ... produce()
condition.signal
condition.unlock
}
}
//consume
dispatch_exe(consume_thread){
while(true){
condition.lock
if(empty){condition.wait}
//...consume()
condition.signal
condition.unlock
}
}
5. @synchronized
(锁对象)
底层封装的pthread_mutex的PTHREAD_MUTEX_RECURSIVE 模式,锁对象来表示是否为同一把锁
6. dispatch_semaphore
//示例1:阻塞发请求的线程
dispatch_exe(queue){
sem = dispatch_semaphore_create(0)
dispatch_exe_async(netrequest)^{ signal(sem)}
wait(sem)
}
//示例2: 控制多个线程并发
sem = dispatch_semaphore_create(n)
for(i:=0;i<n;i++){
dispatch_exe(){
wait(sem)
// do something in per thread
signal(sem)
}
}
优先级反转
- 原因
优先级 task1>task2>task3, 有一个互斥访问的稀缺资源S.- task3正在执行,申请到了S. task1抢占task3并申请资源S,发现已经被占用,所以task3恢复运行.
- task2抢占task3,由于不需要访问S, task2先执行,task执行完 task3恢复
- task3释放资源S, task1抢占 task1执行. 最后执行顺序变成了task2->task1->task3
- 解决方案
task3使用S期间, task1抢占执行申请资源S时,比较task1/task3优先级,如果task1>task3,临时将task3提升到访问S的最高优先级,释放完S后再将task3优先级调整回来