文档章节

iOS并发编程--8种加锁方式及比较

hejunbinlan
 hejunbinlan
发布于 2016/07/21 11:29
字数 589
阅读 47
收藏 0

iOS开发中不可避免的会遇到加锁的情况,今天就来比较一下各种加锁方式。

目前我所知道的有如下几种加锁方式: 
1. @synchronized 关键字加锁 
2. NSLock 对象锁 
3. NSCondition 
4. NSConditionLock 条件锁 
5. NSRecursiveLock 递归锁 
6. pthread_mutex 互斥锁(C语言) 
7. dispatch_semaphore 信号量实现加锁(GCD) 
8. OSSpinLock (暂不建议使用,原因参见这里

这里分别使用8种方式加锁解锁1千万次,执行方法如下:

#import <pthread.h>
#import <libkern/OSAtomic.h>

- (void)runLock{
     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 used : %f\n", timeCurrent-timeBefore);

    //NSLock
    NSLock *lock = [[NSLock alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [lock lock];
        [lock unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSLock used : %f\n", timeCurrent-timeBefore);

    //NSCondition
    NSCondition *condition = [[NSCondition alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [condition lock];
        [condition unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSCondition used : %f\n", timeCurrent-timeBefore);

    //NSConditionLock
    NSConditionLock *conditionLock = [[NSConditionLock alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [conditionLock lock];
        [conditionLock unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSConditionLock used : %f\n", timeCurrent-timeBefore);

    //NSRecursiveLock
    NSRecursiveLock *recursiveLock = [[NSRecursiveLock alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [recursiveLock lock];
        [recursiveLock unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSRecursiveLock used : %f\n", timeCurrent-timeBefore);

    //pthread_mutex
    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 used : %f\n", timeCurrent-timeBefore);

    //dispatch_semaphore
    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 used : %f\n", timeCurrent-timeBefore);

    //OSSpinLockLock
    OSSpinLock spinlock = OS_SPINLOCK_INIT;
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        OSSpinLockLock(&spinlock);
        OSSpinLockUnlock(&spinlock);
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("OSSpinLock used : %f\n", timeCurrent-timeBefore);
}
  • 执行结果: 

执行1千万次的结果

由图可以发现: 
OSSpinLock的性能最好(暂不建议使用),GCD的dispatch_semaphore紧随其后; 
NSConditionLock和@synchronized性能较差;

PS: 
1. 需要注意的是这里仅仅是对各种锁直接Lock和Unlock的性能测试,其中部分锁的使用条件上还是有细微的差异的,比如NSLock之类的还有tryLock等方法用于加锁,不同对象锁的功能偏向不一样等等,有兴趣的可以逐个搜索再更深入的研究不同锁之间的区别。 
2. 另外,一般来说客户端很少会有这么大量的加锁解锁操作,所以日常来说这些锁的性能都是可以满足使用需求的。

本文对于iOS中的锁也是抛砖引玉,欢迎各位留言讨论。

本文转载自:http://blog.csdn.net/u010124617/article/details/45822625

hejunbinlan
粉丝 42
博文 596
码字总数 21569
作品 0
浦东
高级程序员
私信 提问
2018 iOS 面试题大全(补充完整版)

原文地址:2018 iOS 面试题大全 由于原作者并没有继续更新,这里我转过来继续更新下 这个栏目将持续更新--请iOS的小伙伴关注! 1、iOS 应用导航模式有哪些? 2、iOS 中持久化方式有哪些? 3、...

Theendisthebegi
2018/11/15
0
0
iOS播放器、Flutter高仿书旗小说、卡片动画、二维码扫码、菜单弹窗效果等源码

iOS精选源码 全网最详细购物车强势来袭(http://www.code4app.com/thread-10664-1-1.html) 一款优雅易用的微型菜单弹窗(类似QQ和微信右上角弹窗)(http://www.code4app.com/thread-12069-1-1....

Android爱开源
01/23
257
0
10个优秀Objective-C和iOS开发在线视频教程

如果你自己开发iOS应用,你肯定会发现网上有很多资源。学习编程的一个最好的方法就是自己写代码,而开始写代码的最快的方式就是看其他人怎么写。我们从海量视频和学习网站中整理出了我们认为...

mingxun
2014/05/09
193
0
iOS开发系列--并行开发其实很容易

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jianxin160/article/details/47753225 --多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时...

KenshinCui
2015/08/18
0
0
[C++][IO]fstream用法

fstream用法 1. 打开文件 在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是: void open(const char* filename,int mode,int access); 参数: filename:  要打开的文件...

guitar_zp
2011/08/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周日乱弹 —— 别问,问就是没空

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享容祖儿/彭羚的单曲《心淡》: 《心淡》- 容祖儿/彭羚 手机党少年们想听歌,请使劲儿戳(这里) @wqp0010 :周...

小小编辑
今天
323
7
golang微服务框架go-micro 入门笔记2.1 micro工具之micro api

micro api micro 功能非常强大,本文将详细阐述micro api 命令行的功能 重要的事情说3次 本文全部代码https://idea.techidea8.com/open/idea.shtml?id=6 本文全部代码https://idea.techidea8....

非正式解决方案
今天
5
0
Spring Context 你真的懂了吗

今天介绍一下大家常见的一个单词 context 应该怎么去理解,正确的理解它有助于我们学习 spring 以及计算机系统中的其他知识。 1. context 是什么 我们经常在编程中见到 context 这个单词,当...

Java知其所以然
昨天
5
0
Spring Boot + Mybatis-Plus 集成与使用(二)

前言: 本章节介绍MyBatis-Puls的CRUD使用。在开始之前,先简单讲解下上章节关于Spring Boot是如何自动配置MyBatis-Plus。 一、自动配置 当Spring Boot应用从主方法main()启动后,首先加载S...

伴学编程
昨天
8
0
用最通俗的方法讲spring [一] ──── AOP

@[TOC](用最通俗的方法讲spring [一] ──── AOP) 写这个系列的目的(可以跳过不看) 自己写这个系列的目的,是因为自己是个比较笨的人,我曾一度怀疑自己的智商不适合干编程这个行业.因为在我...

小贼贼子
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部