前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS中的常用一些锁

iOS中的常用一些锁

原创
作者头像
新用户
修改2018-09-20 14:59:09
9420
修改2018-09-20 14:59:09
举报
文章被收录于专栏:学习笔记iOS学习笔记iOS

引言

我们在多线程编程中常常会使用一些锁来保证程序的线程安全,这篇主要就是介绍一些iOS中常用锁,以及通过一个简单的demo来测试一些锁的性能。

锁的分类

锁只要分为以下几类:

互斥锁

互斥锁它将代码切片成为一个个临界区(代码片段),使得当一个代码片段在运行时,其他线程不能运行它们之中的任意片段,只有等到该片段结束运行后才可以运行。通过这种方式来防止多个线程同时对某一资源进行读写的一种机制。

读写锁

是并发控制的一种同步机制,有的地方也称为“共享-互斥锁”,也是一种特殊的自旋锁。它把对资源的访问者分为读者和写者。它允许同时有多个读者来访问资源,但是只允许一个写者来访问资源。

自旋锁

多线程同步的一种锁,当其检测到资源不可用时,则保持一种“忙等”的状态,知道获取该资源。因此它的优势在于避免了线程上下文的进度的切换,非常适合于阻塞时间很短的场合。缺点则是在“忙等”的状态下会不停检测状态,占用一点的cpu资源。

条件锁

顾名思义,就是通过一些条件来控制资源的访问,当然条件是会发生变化的。

信号量

是一种高级的同步机制。互斥锁可以认为是型号量取值0/1时的特例,可以实现更加复杂的同步。

性能分析

通过一个简单的demo来分析iOS中常用的一些锁的性能(@synchronized,NSLock,pthread,OSSpinLock,dispatch_semaphore_t,pthread_mutex_t,NSCondition,NSRecursiveLock,NSConditionLock,pthread_rwlock_t,os_unfair_lock_t,pthread_mutex_recursive)

demo的主要代码如下:

代码语言:txt
复制
NSTimeInterval begin, end; //定义锁的开始时间和结束时间
代码语言:txt
复制
// OSSpinLock 自旋锁
    {
        OSSpinLock lock = OS_SPINLOCK_INIT;
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            OSSpinLockLock(&lock);
            OSSpinLockUnlock(&lock);
        }
        end = CACurrentMediaTime();
        timeCosts = end - begin;
    }
代码语言:txt
复制
//  dispatch_semaphore_t 信号量
        dispatch_semaphore_t lock =  dispatch_semaphore_create(1);
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
            dispatch_semaphore_signal(lock);
        }
        end = CACurrentMediaTime();
        timeCosts = end - begin;
代码语言:txt
复制
// pthread_mutex_t 
        pthread_mutex_t lock;
        pthread_mutex_init(&lock, NULL);
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            pthread_mutex_lock(&lock);
            pthread_mutex_unlock(&lock);
        }
        end = CACurrentMediaTime();
        timeCosts = end - begin;
        pthread_mutex_destroy(&lock);
代码语言:txt
复制
// NSCondition 条件锁
        NSCondition *lock = [NSCondition new];
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            [lock lock];
            [lock unlock];
        }
        end = CACurrentMediaTime();
        timeCosts = end - begin;
代码语言:txt
复制
// NSLock
        NSLock *lock = [NSLock new];
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            [lock lock];
            [lock unlock];
        }
        end = CACurrentMediaTime();
        timeCosts = end - begin;
代码语言:txt
复制
        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);
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            pthread_mutex_lock(&lock);
            pthread_mutex_unlock(&lock);
        }
        end = CACurrentMediaTime();
        timeCosts = end - begin;
        pthread_mutex_destroy(&lock);
代码语言:txt
复制
// NSRecursiveLock 递归锁
        NSRecursiveLock *lock = [NSRecursiveLock new];
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            [lock lock];
            [lock unlock];
        }
        end = CACurrentMediaTime();
        timeCosts = end - begin;
代码语言:txt
复制
// NSConditionLock
        NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:1];
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            [lock lock];
            [lock unlock];
        }
        end = CACurrentMediaTime();
        timeCosts = end - begin;
代码语言:txt
复制
// pthread_rwlock_t 读写锁
        pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            pthread_rwlock_wrlock(&rwlock);
            pthread_rwlock_unlock(&rwlock);
        }
        end = CACurrentMediaTime();
        timeCosts = end - begin;
代码语言:txt
复制
// os_unfair_lock_t iOS10之后的替换自旋锁的
        os_unfair_lock_t unfairLock;
        unfairLock = &(OS_UNFAIR_LOCK_INIT);
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            os_unfair_lock_lock(unfairLock);
            os_unfair_lock_unlock(unfairLock);
        }
        end = CACurrentMediaTime();
        TimeCosts[LockTypeos_unfair_lock] += end - begin;
        timeCosts[LockTypeos_unfair_lock] = end - begin;
代码语言:txt
复制
// synchronized
        NSObject *lock = [NSObject new];
        begin = CACurrentMediaTime();
        for (int i = 0; i < count; i++) {
            @synchronized(lock) {}
        }
        end = CACurrentMediaTime();
        TimeCosts[LockTypesynchronized] += end - begin;
        timeCosts[LockTypesynchronized] = end - begin;

上述代码均为加锁解锁的操作,在重复1000000次加锁解锁的基础进行测试(模拟器中),结果数据如下:

OSSpinLock

os_unfair_lock

dispatch_semaphore

pthread_mutex

NSCondition

NSLock

pthread_rwlock

pthread_mutex(recursive)

NSRecursiveLock

NSConditionLock

@synchronized

13.31 ms

15.03 ms

18.33 ms

23.85 ms

24.08 ms

26.65 ms

28.21 ms

37.22 ms

48.09 ms

88.04 ms

137.27 ms

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 锁的分类
    • 互斥锁
      • 读写锁
        • 自旋锁
          • 条件锁
            • 信号量
            • 性能分析
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档