iOS 安全锁原理集合

 联系人:石虎 QQ:1224614774  昵称: 嗡嘛呢叭咪哄

                      QQ群:807236138  群称: iOS 技术交流学习群

一、概念

我们在使用多线程的时候多个线程可能会访问同一块资源,这样就很容易引发数据错乱和数据安全等问题,这时候就需要我们保证每次只有一个线程访问这一块资源,锁 应运而生。

效率图:

石虎安全锁. png

二、锁🔐锁

OSSpinLock (自旋锁)

      自旋锁的实现原理比较简单,就是死循环。当a线程获得锁以后,b线程想要获取锁就需要等待a线程释放锁。在没有获得锁的期间,b线程会一直处于忙等的状态。如果a线程在临界区的执行时间过长,则b线程会消耗大量的cpu时间,不太划算。所以,自旋锁用在临界区执行时间比较短的环境性能会很高。

注:苹果爸爸已经在iOS10.0以后废弃了这种锁机制,使用os_unfair_lock 替换,

     顾名思义能够保证不同优先级的线程申请锁的时候不会发生优先级反转问题.

os_unfair_lock(自旋锁)

注:解决不同优先级的线程申请锁的时候不会发生优先级反转问题.

    不过相对于 OSSpinLock , os_unfair_lock性能方面减弱了许多.

dispatch_semaphore (信号量)

注: dispatch_semaphore  其他两个功能

     1.还可以起到阻塞线程的作用.

     2.可以实现定时器功能,这里不做过多介绍.

pthread_mutex(互斥锁)

pthread_mutex表示互斥锁,和信号量的实现原理类似,也是阻塞线程并进入睡眠,需要进行上下文切换。

pthread_mutexattr_t attr;

pthread_mutexattr_init(&attr);

pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);

pthread_mutex_t lock;

pthread_mutex_init(&lock, &attr);    //设置属性

pthread_mutex_lock(&lock);    //上锁

//需要执行的代码

pthread_mutex_unlock(&lock);    //解锁

NSLock(互斥锁、对象锁)

NSLock在内部封装了一个 pthread_mutex,属性为 PTHREAD_MUTEX_ERRORCHECK。

NSLock *lock = [NSLock new];

[lock lock];

//需要执行的代码

[lock unlock];

NSCondition(条件锁、对象锁)

NSCondition封装了一个互斥锁和条件变量。互斥锁保证线程安全,条件变量保证执行顺序。

NSCondition *lock = [NSCondition new];

[lock lock];

//需要执行的代码

[lock unlock];

pthread_mutex(recursive)(递归锁)

pthread_mutex锁的一种,属于递归锁。一般一个线程只能申请一把锁,但是,如果是递归锁,则可以申请很多把锁,只要上锁和解锁的操作数量就不会报错。

pthread_mutexattr_t attr;

pthread_mutexattr_init(&attr);

pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

pthread_mutex_t lock;

pthread_mutex_init(&lock, &attr); //设置属性

pthread_mutex_lock(&lock);       //上锁

//需要执行的代码

pthread_mutex_unlock(&lock);     //解锁

注: 递归锁可以被同一线程多次请求,而不会引起死锁。

即在同一线程中在未解锁之前还可以上锁, 执行锁中的代码。

这主要是用在循环或递归操作中。

NSRecursiveLock(递归锁、对象锁)

递归锁,pthread_mutex(recursive)的封装。

NSRecursiveLock *lock = [NSRecursiveLock new];

[lock lock];

//需要执行的代码

[lock unlock];

NSConditionLock(条件锁、对象锁)

NSConditionLock借助 NSCondition 来实现,本质是生产者-消费者模型。

NSConditionLock *lock = [NSConditionLock new];

[lock lock];

//需要执行的代码

[lock unlock];

@synchronized(条件锁)

一个对象层面的锁,锁住了整个对象,底层使用了互斥递归锁来实现。

NSObject *object = [NSObject new];

@synchronized(object) {

    //需要执行的代码

}

三、总结

@synchronized互斥锁:当上一个线程的任务没有执行完毕的时候(被锁住),那么下一个线程会进入睡眠状态等待任务执行完毕,当上一个线程的任务执行完毕,下一个线程会自动唤醒然后执行任务。

应用场景: @synchronized:适用线程不多,任务量不大的多线程加锁

注意点:

1.如果多线程访问同一个资源,那么必须使用同一把锁才能锁住

2.在开发中,尽量不要加锁,能在服务端做尽量在服务端做,如果必须要加锁,一定要记住,锁的范围不能太大,哪里有安全隐患就加在哪里。

3.技巧:因为必须使用同一把锁,开发中如果需要加锁,直接使用 self 即可。

@synchronized(self) {//加锁

}//解锁

atomic 自旋锁:当上一个线程的任务没有执行完毕的时候(被锁住),那么下一个线程会一直等待(不会睡眠),当上一个线程的任务执行完毕,下一个线程会立即执行。

atomic 自旋锁应用场景:比较适合做一些不耗时的操作

注意点:

只会给 setter 方法加锁,并不会给getter方法加锁

NSLock:其实NSLock并没有想象中的那么差,不知道大家为什么不推荐使用

dispatch_semaphore_t:使用信号来做加锁,性能提升显著

NSCondition:使用其做多线程之间的通信调用不是线程安全的

NSConditionLock:单纯加锁性能非常低,比NSLock低很多,但是可以用来做多线程处理不同任务的通信调用

NSRecursiveLock:递归锁的性能出奇的高,但是只能作为递归使用,所以限制了使用场景

NSDistributedLock:因为是MAC开发的,就不讨论了

POSIX(pthread_mutex):底层的api,复杂的多线程处理建议使用,并且可以封装自己的多线程

OSSpinLock:性能也非常高,可惜出现了线程问题

dispatch_barrier_async/dispatch_barrier_sync:测试中发现dispatch_barrier_sync比dispatch_barrier_async性能要高,真是大出意外

谢谢!!! 

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容

  • 锁是一种同步机制,用于多线程环境中对资源访问的限制iOS中常见锁的性能对比图(摘自:ibireme): iOS锁的...
    LiLS阅读 1,458评论 0 6
  • iOS线程安全的锁与性能对比 一、锁的基本使用方法 1.1、@synchronized 这是我们最熟悉的枷锁方式,...
    Jacky_Yang阅读 2,137评论 0 17
  • 转载自:https://www.jianshu.com/p/938d68ed832c# 一、前言 前段时间看了几个...
    cafei阅读 4,505评论 1 12
  • 一、前言 前段时间看了几个开源项目,发现他们保持线程同步的方式各不相同,有@synchronized、NSLock...
    稻春阅读 454评论 0 0
  • (转载) iOS 各种锁机制 一、前言 前段时间看了几个开源项目,发现他们保持线程同步的方式各不相同,有@syn...
    北漂老张阅读 435评论 0 1