美文网首页
iOS 中的各种锁

iOS 中的各种锁

作者: 含笑州 | 来源:发表于2019-03-06 09:12 被阅读0次

    简单的性能测试

    互斥锁

    1.NSLock:是Foundation框架中以对象形式暴露给开发者的一种锁

    缺点:多次lock会造成线程死锁。

    2.pthread_mutex

    3.@synchronized:

    实际项目中:AFNetworking中 isNetworkActivityOccurring属性的getter方法

    - (BOOL)isNetworkActivityOccurring {

        @synchronized(self) {

            return self.activityCount > 0;

        }

    }

    自旋锁

    1.OSSpinLock:

    OSSpinLock lock = OS_SPINLOCK_INIT;

    OSSpinLockLock(&lock);

    ...

    OSSpinLockUnlock(&lock);

    上面是OSSpinLock使用方式,编译会报警告,已经废弃了,OSSpinLock大家也已经不再用它了,因为它在某一些场景下已经不安全了,可以参考 YY大神的不再安全的 OSSpinLock,在Protocol Buffers项目中你可以看到这样的注释,大家已经用新的方案替换了。

    // NOTE:OSSpinLock may seem like a good fit here but Apple engineers have// pointed out that they are vulnerable to live locking on iOS in cases of// priority inversion:// http://mjtsai.com/blog/2015/12/16/osspinlock-is-unsafe/// https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20151214/000372.html

    2.os_unfair_lock:

    os_unfair_lock 是苹果官方推荐的替换OSSpinLock的方案,但是它在iOS10.0以上的系统才可以调用。

    os_unfair_lock_t unfairLock;

    unfairLock = &(OS_UNFAIR_LOCK_INIT);

    os_unfair_lock_lock(unfairLock);

    os_unfair_lock_unlock(unfairLock);

    读写锁

    上文有说到,读写锁又称共享-互斥锁,

    pthread_rwlock:

    //加读锁

    pthread_rwlock_rdlock(&rwlock);

    //解锁

    pthread_rwlock_unlock(&rwlock);

    //加写锁

    pthread_rwlock_wrlock(&rwlock);

    //解锁

    pthread_rwlock_unlock(&rwlock);

    递归锁

    递归锁有一个特点,就是同一个线程可以加锁N次而不会引发死锁。

    1.NSRecursiveLock:

    NSRecursiveLock在YYKit中YYWebImageOperation.m中有用到:

    _lock = [NSRecursiveLock new];

    - (void)dealloc {

        [_lock lock];

        ...

        ...

        [_lock unlock];

    }

    2.pthread_mutex(recursive):

    pthread_mutex锁也支持递归,只需要设置PTHREAD_MUTEX_RECURSIVE即可

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

    条件锁

    1.NSCondition:

    定义:

    @interface NSCondition : NSObject <NSLocking> {

    @private

        void *_priv;

    }

    - (void)wait;

    - (BOOL)waitUntilDate:(NSDate *)limit;

    - (void)signal;

    - (void)broadcast;

    遵循NSLocking协议,使用的时候同样是lock,unlock加解锁,wait是傻等,waitUntilDate:方法是等一会,都会阻塞掉线程,signal是唤起一个在等待的线程,broadcast是广播全部唤起。

    NSCondition *lock = [[NSCondition alloc] init];

    //Son 线程

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [lock lock];

        while (No Money) {

            [lock wait];

        }

        NSLog(@"The money has been used up.");

        [lock unlock];

    });

    //Father线程

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [lock lock];

        NSLog(@"Work hard to make money.");

        [lock signal];

        [lock unlock];

    });

    2.NSConditionLock:

    定义:

    @interface NSConditionLock : NSObject <NSLocking> {

    @private

        void *_priv;

    }

    - (instancetype)initWithCondition:(NSInteger)condition NS_DESIGNATED_INITIALIZER;

    @property (readonly) NSInteger condition;

    - (void)lockWhenCondition:(NSInteger)condition;

    - (BOOL)tryLock;

    - (BOOL)tryLockWhenCondition:(NSInteger)condition;

    - (void)unlockWithCondition:(NSInteger)condition;

    - (BOOL)lockBeforeDate:(NSDate *)limit;

    - (BOOL)lockWhenCondition:(NSInteger)condition beforeDate:(NSDate *)limit;

    很简单,方法很清晰,基本同上。

    分布式锁

    NSDistributedLock

    NSDistributedLock是MAC开发中的跨进程的分布式锁,底层是用文件系统实现的互斥锁。NSDistributedLock没有实现NSLocking协议,所以没有lock方法,取而代之的是非阻塞的tryLock方法。

    NSDistributedLock*lock = [[NSDistributedLockalloc] initWithPath:@"/Users/mac/Desktop/lock.lock"];while(![lock tryLock]) { sleep(1); }//do something[lock unlock];

    当执行到do something时程序退出,程序再次启动之后tryLock就再也不能成功了,陷入死锁状态.其他应用也不能访问受保护的共享资源。在这种情况下,你可以使用breadLock方法来打破现存的锁以便你可以获取它。但是通常应该避免打破锁,除非你确定拥有进程已经死亡并不可能再释放该锁

    信号量

    dispatch_semaphore:

    // 初始化dispatch_semaphore_tsemaphore_t= dispatch_semaphore_create(1);// 加锁dispatch_semaphore_wait(semaphore_t,DISPATCH_TIME_FOREVER);// 解锁dispatch_semaphore_signal(semaphore_t);/* 注: dispatch_semaphore 其他两个功能 1.还可以起到阻塞线程的作用. 2.可以实现定时器功能,这里不做过多介绍.

    相关文章

      网友评论

          本文标题:iOS 中的各种锁

          本文链接:https://www.haomeiwen.com/subject/xsyouqtx.html