1:互斥锁
测试代码
使用3个线程,每个线程加1w次,测试各个互斥锁的性能
注意使用锁的时候,不要将锁声明为 @property,这样会生成set方法和get方法,每次加锁都会调用get方法,这样降低了锁的性能
#import <mach/mach_time.h>
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("group.queue", DISPATCH_QUEUE_CONCURRENT);
uint64_t start = mach_absolute_time();;
dispatch_group_async(group, queue, ^{
for (int i=0; i < 10000; i++) {
[self add];
}
});
dispatch_group_async(group, queue, ^{
for (int i=0; i < 10000; i++) {
[self add];
}
});
dispatch_group_async(group, queue, ^{
for (int i=0; i < 10000; i++) {
[self add];
}
});
dispatch_group_notify(group, queue, ^{
uint64_t end = mach_absolute_time();
NSLog(@"finish:%d %d",end - start,self.count);
});
- (void)add{
//这里更换各种锁
[self.lock lock];
self.count++;
[self.lock unlock];
// @synchronized (self) {
// self.count++;
// }
}
NSLock
NSLock lock = [[NSLock alloc] init];
[lock lock];
临界区
[lock unlock];
第一个数是所需的cpu时钟周期
synchronized
@synchronized (self) {
self.count++;
}
synchronized 的性能是最差的
pthread_mutex_t
#include <pthread.h>
pthread_mutex_t _plock;
pthread_mutex_init(&_plock, NULL);
pthread_mutex_lock(&_plock);
临界区
pthread_mutex_unlock(&_plock);
果然底层框架速度是最快的
2:自旋锁
OSSpinLock: 据说已经废弃,因为会导致优先级低的任务始终无法获取cpu时间片
os_unfair_lock_t: 作为 OSSpinLock 的替代品,是一种互斥锁,但是在使用的时候莫名崩溃,原因不明。
#import <os/lock.h>
os_unfair_lock_t _unfairLock = &(OS_UNFAIR_LOCK_INIT);
os_unfair_lock_lock(_unfairLock);
临界资源
os_unfair_lock_unlock(_unfairLock);
3:读写锁
操作系统中,有个经典问题就是读写者问题,读写者问题中,临界区资源允许多个线程读,但只允许一个线程写。
pthread_rwlock_t _rwlock;
pthread_rwlock_init(&_rwlock, NULL);
//加读锁
pthread_rwlock_rdlock(&rwlock);
//解锁
pthread_rwlock_unlock(&rwlock);
//加写锁
pthread_rwlock_wrlock(&rwlock);
//解锁
pthread_rwlock_unlock(&rwlock);
4:递归锁
当我们给临界资源加多把锁的时候,会出现死锁问题,递归锁就可以避免这种问题。
NSRecursiveLock
NSRecursiveLock * _rlock;
_rlock = [[NSRecursiveLock alloc] init];
[_rlock lock];
临界资源
[_rlock unlock];
但是递归锁的效率不高,不过还是好于 synchronized
一层锁所需时间
两层锁所需时间
pthread_mutex_t 也支持递归锁,使用方式如下
pthread_mutex_t lock;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&lock, &attr);
pthread_mutexattr_destroy(&attr);
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
5:条件锁 NSCondition
@interface NSCondition : NSObject <NSLocking> {
@private
void *_priv;
}
- (void)wait; //等待
- (BOOL)waitUntilDate:(NSDate *)limit; //等待到一段时间
- (void)signal; //唤起一个等待的线程
- (void)broadcast; //广播,唤起全部线程
NSCondition *lock = [[NSCondition alloc] init];
[lock lock];
临界资源
[lock wait]; //等一会儿,还不想出临界区,等其他线程调用 signal 或者broadcast
[lock unlock];
6:信号量
这个基本上能解决多线程的所有问题,当信号量值设置为1的时候,能够解决互斥问题,设置为其他值,能够解决读写者问题、生产者消费者问题等(具体看操作系统原理)
dispatch_semaphore_t _mutex;
_mutex = dispatch_semaphore_create(1);
dispatch_semaphore_wait(_mutex, DISPATCH_TIME_FOREVER);
self.count++;
dispatch_semaphore_signal(_mutex);
不知道是不是实验出了问题,使用信号量解决互斥问题,速度很慢