# 互斥锁
是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写的机制。该目的通过将代码切片成一个一个的临界区而达成。
1.NSLock:是Foundation框架中以对象形式暴露给开发者的一种锁
实际项目中:NSLock在AFNetworking的AFURLSessionManager.m中应用如下:
-(instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
...
self.lock = [[NSLock alloc] init];
self.lock.name = AFURLSessionManagerLockName;
...
}
-(void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate
forTask:(NSURLSessionTask *)task
{
...
[self.lock lock];
self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
[delegate setupProgressForTask:task];
[self addNotificationObserverForTask:task];
[self.lock unlock];
}
2.pthread_mutex:
实际项目中: 在YYKit的YYMemoryCach中可以看到
-(instancetype)init {
...
pthread_mutex_init(&_lock, NULL);
...
}
-(void)_trimToCost:(NSUInteger)costLimit {
BOOL finish = NO;
pthread_mutex_lock(&_lock);
if (costLimit == 0) {
[_lru removeAll];
finish = YES;
} else if (_lru->_totalCost <= costLimit) {
finish = YES;
}
pthread_mutex_unlock(&_lock);
if (finish) return;
NSMutableArray *holder = [NSMutableArray new];
while (!finish) {
if (pthread_mutex_trylock(&_lock) == 0) {
if (_lru->_totalCost > costLimit) {
_YYLinkedMapNode *node = [_lru removeTailNode];
if (node) [holder addObject:node];
} else {
finish = YES;
}
pthread_mutex_unlock(&_lock);
} else {
usleep(10 * 1000); //10 ms
}
}
...
}
3.@synchronized:
实际项目中:AFNetworking中 isNetworkActivityOccurring属性的getter方法
-(BOOL)isNetworkActivityOccurring {
@synchronized(self) {
return self.activityCount > 0;
}
}
## 互斥锁和自旋锁
1.互斥锁:同一时刻只能有一个线程获得互斥锁,其他线程处于挂起状态。
这期间涉及上下文的切换,CPU的抢占,以及信号发送开销,使用于需要处理一段时间才能完成的事务,即处理一段时间后才将锁释放。
互斥锁:pthread_mutex、@ synchronized、NSLock、NSConditionLock 、NSCondition、NSRecursiveLock
2.自旋锁: 当A线程获得锁之后,B线程会一直做do...While循环,尝试获得锁。
自旋锁当超过了限定的次数仍然没有成功获得锁时,线程也会被挂起,自旋锁相当于B线程一直在做do while循环(一直消耗CPU时间),检测锁是否释放。一般用于锁很快释放的场景。由于不涉及上下文切换那些操作,对于处理锁持有者保存时间比较短的情况,效率比互斥锁高
自旋锁:atomic、OSSpinLock、dispatch_semaphore_t
## 锁 是什么意思?
我们在使用多线程的时候多个线程可能会访问同一块资源,这样就很容易引发数据错乱和数据安全等问题,这时候就需要我们保证每次只有一个线程访问这一块资源,锁 应运而生。
## 锁的使用
https://www.jianshu.com/p/8b8a01dd6356
## 线程死锁
线程死锁的4个必要条件:
1.互斥:一个资源每次只能被一个进程使用
2.占有且等待:一个进程本身占有资源(一种或多种),同时还有资源未得到满足,正在等待其他进程释放该资源
3.不可抢占:别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来
4.循环等待:存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。