iOS中各种锁的性能对比

作者: o0阿拉斯加的狗0o | 来源:发表于2016-11-27 23:34 被阅读757次

自旋锁 与 互斥锁

  • 自旋锁 (spin lock): 如果一个线程需要获取自旋锁,该锁已经被其他线程占用,该线程不会被挂起,而是不断消耗CPU时间,一直试图获取自旋锁。
  • 互斥锁 (mutex):如果一个线程无法获取互斥量,该线程会被直接挂起,不再小号CPU时间,当其他线程释放互斥量后,操作系统会激活被挂起的线程。

使用场景:

  • 多核处理器:如果预计线程等待锁的时间比较短,短到比线程两次切换上下文的时间还要少的情况下,自旋锁是更好的选择。如果时间比较长,则互斥锁是比较好的选择。
  • 单核处理器:一般不建议使用自旋锁。因为在同一时间片内只有一个线程处在运行状态,如果线程a已经获取到锁,但是此时时间片轮到线程b执行,但是线程b获取锁,只能等待解锁,但是因为自己不挂起,所以线程a无法进入运行状态,只能等到线程b的时间片消耗完,线程a才有机会被OS调度执行。此时使用自旋锁的代价很高。

如果加锁的代码经常被调用,但是竞争发生的比较少时,应该优先考虑使用自旋锁,毕竟互斥锁的切换上下文的开销比较大。

性能对比

iOS中的锁包括:

  • @synchronized
  • NSLock
  • NSCondition
  • NSConditionLock
  • NSRecursiveLock
  • pthread_mutex_t
  • dispatch_semaphore_t
  • OSSpinLock

做的测试是对每种锁进行100万次的加锁解锁操作,对比时间,使用的iPhone6iOS10.1.1的设备,测试结果如下:

各种锁的时间性能对比

从对比可以看出,性能最优的是OSSpinLock ,最差的是@synchronized,下面是我制作的各种锁的性能对比,不同的系统和设备的数值可能会有差异:

iOS中各种锁的性能对比

<h3 align = "center">测试代码</h3>

<a name="fenced-code-block">@synchronized()</a>

    CFTimeInterval timeBefore;
    CFTimeInterval timeCurrent;
    NSUInteger i;
    NSUInteger count = 1000*10000;//执行一千万次

    //@synchronized
    id obj = [[NSObject alloc]init];;
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        @synchronized(obj){
        }
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("@synchronized  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">NSLock</a>
    NSLock *lock = [[NSLock alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [lock lock];
        [lock unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSLock  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">NSCondition</a>
    NSCondition *condition = [[NSCondition alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [condition lock];
        [condition unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSCondition  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">NSConditionLock</a>
    NSConditionLock *conditionLock = [[NSConditionLock alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [conditionLock lock];
        [conditionLock unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSConditionLock  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">NSRecursiveLock</a>
    NSRecursiveLock *recursiveLock = [[NSRecursiveLock alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [recursiveLock lock];
        [recursiveLock unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSRecursiveLock  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">pthread_mutex_t</a>
 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        pthread_mutex_lock(&mutex);
        pthread_mutex_unlock(&mutex);
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("pthread_mutex  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">dispatch_semaphore_t</a>
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_signal(semaphore);
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("dispatch_semaphore  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">OSSpinLock</a>
    OSSpinLock spinlock = OS_SPINLOCK_INIT;
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        OSSpinLockLock(&spinlock);
        OSSpinLockUnlock(&spinlock);
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("OSSpinLock  : %f\n", timeCurrent-timeBefore);

相关文章

  • iOS中各种锁的性能对比

    自旋锁 与 互斥锁 自旋锁 (spin lock): 如果一个线程需要获取自旋锁,该锁已经被其他线程占用,该线程不...

  • iOS 锁的使用

    参考 demo 参考的文章:iOS开发中的11种锁以及性能对比多线程-线程安全 结论: 自旋锁性能 > 信号量 >...

  • 2021-03-05

    1.锁(递归锁的实现原理) iOS开发中的11种锁以及性能对比 - 简书[https://www.jianshu....

  • iOS中的锁

    锁是一种同步机制,用于多线程环境中对资源访问的限制iOS中常见锁的性能对比图(摘自:ibireme): iOS锁的...

  • iOS底层探索--@synchronized线程锁

      iOS中各种锁性能对比,建立一个10万次的循环,加锁、解锁,对比前后时间差得到其耗时时间。以下是真实的测试结果...

  • iOS线程安全的锁与性能对比

    iOS线程安全的锁与性能对比 一、锁的基本使用方法 1.1、@synchronized 这是我们最熟悉的枷锁方式,...

  • 各种锁介绍以及性能对比

    多线程为我们带来了很大便利,也提高了程序的执行效率,但同时也带来了Data race(当至少有两个线程同时访问同一...

  • 锁分析(上)

    锁性能分析 iPhone 12真机测试,锁的性能数据对比图 性能从高到低排序:OSSpinLock(自旋锁)>os...

  • ios开发中的各种锁机制

    ios开发中的各种锁机制

  • iOS 中的各种锁

    在日常开发过程中,为了提升程序运行效率,以及用户体验,我们经常使用多线程。在使用多线程的过程中,难免会遇到资源竞争...

网友评论

    本文标题:iOS中各种锁的性能对比

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