iOS中的各种锁

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);

不知道是不是实验出了问题,使用信号量解决互斥问题,速度很慢
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/goldfish3/article/details/89438630