你用过哪些锁?对于锁的种类你了解多少?锁的原理知道否?从本篇博客开始将对的相关内容进行分析!

iOS底层探索之多线程(一)—进程和线程

iOS底层探索之多线程(二)—线程和锁

iOS底层探索之多线程(三)—初识GCD

iOS底层探索之多线程(四)—GCD的队列

iOS底层探索之多线程(五)—GCD不同队列源码分析

iOS底层探索之多线程(六)—GCD源码分析(sync 同步函数、async 异步函数)

iOS底层探索之多线程(七)—GCD源码分析(死锁的原因)

iOS底层探索之多线程(八)—GCD源码分析(函数的同步性、异步性、单例)

iOS底层探索之多线程(九)—GCD源码分析(栅栏函数)

iOS底层探索之多线程(十)—GCD源码分析( 信号量)

iOS底层探索之多线程(十一)—GCD源码分析(调度组)

iOS底层探索之多线程(十二)—GCD源码分析(事件源)

1.锁的介绍

在 iOS 中有以下九种锁

  1. OSSpinLock:(自旋锁)
  2. dispatch_semaphore_t:(信号量/互斥锁)
  3. os_unfair_lock_lock:(自旋锁)
  4. pthread_mutex_t:(互斥递归锁)
  5. NSLock:(互斥锁)
  6. NSCondition:(条件锁)
  7. NSRecursiveLock:(递归锁)
  8. NSConditionLock:(条件锁)
  9. @synchronized:(内部是互斥锁)

通过对以上的进行 加锁/解锁 10万次的测试表现,结果如下

  1. iPhone12 模拟器
  • 性能测试统计图表如下
  1. iPhoneXR 模拟器

  2. iPhoneXR 真机

    通过以上测试,的性能最好的前三位是:OSSpinLock(自旋锁) -> dispatch_semaphone(信号量) -> pthread_mutex(互斥锁) ,最差的是synchronized(互斥锁),但也是我们最常用的锁之一。

2. 锁的分类

锁分为两大类,自旋锁互斥锁

自旋锁

是一种用于保护多线程共享资源的锁,与一般互斥锁mutex)不同之处在于当自旋锁尝试获取锁时以忙等待busy waiting)的形式不断地循环检查锁是否可用。当上一个线程的任务没有执行完毕的时候(被锁住),那么下一个线程会一直等待(不会睡眠),当上一个线程的任务执行完毕,下一个线程会立即执行。
在多CPU的环境中,对持有锁较短的程序来说,使用自旋锁代替一般的互斥锁往往能够提高程序的性能。

自旋锁:OSSpinLock(自旋锁)、读写锁

  1. 自旋锁
  • OSSpinLock
  • os_unfair_lock_lock
  1. 互斥锁
  • pthread_mutex_t
  • NSLock
  • NSCondition
  • NSRecursiveLock
  • NSConditionLock
  • dispatch_semaphore_t
  • @synchronized (内部是)

互斥锁

当上一个线程的任务没有执行完毕的时候(被锁住),那么下一个线程会进入睡眠状态等待任务执行完毕,当上一个线程的任务执行完毕,下一个线程会自动唤醒然后执行任务,该任务也不会立刻执行,而是成为可执行状态(就绪)。

互斥锁(mutex),⽤于保证在任何时刻,都只能有⼀个线程访问该对象。
mutex函数
Posix Thread中定义有⼀套专⻔⽤于线程同步的mutex函数。mutex⽤于保证在任何时刻,都只能有⼀个线程访问该对象。当获取锁操作失败时,线程会进⼊睡眠,等待锁释放时被唤醒。NSLock、NSCondtion、NSRecursiveLock底层都是对pthread的封装。

互斥和同步的理解

互斥:两条线程处理,同一时间只有一个线程可以运行;
同步:除了有互斥的意思外,同时还有一定的顺序要求,即按照一定的顺序执行。

递归锁

就是同⼀个线程可以加锁N次⽽不会引发死锁NSRecursiveLock、@synchronized、pthread_mutex(recursive)

互斥锁pthread_mutex(互斥锁)@synchronized(互斥锁)NSLock(互斥锁)NSConditionLock(条件锁)NSCondition(条件锁)NSRecursiveLock(递归锁)dispatch_semaphore_t(信号量)

自旋锁和互斥锁的特点

自旋锁忙等,所谓忙等,即在访问被锁资源时,调用者线程不会休眠,而是一直地不停循环在那里,直到被锁资源释放锁,就和上 WC一样,里面有人了,门锁住了,你一直在门外等着,一直敲门询问,好了吗?好了没有啊?。

互斥锁休眠,所谓休眠,即在访问被锁资源时,调用者线程会休眠,此时cpu可以调度其他线程工作,直到被锁资源释放锁,此时会唤醒休眠线程。就是你知道厕所有人了,你先憋着,不会一直敲门询问,等里面的人好了,你在就去。

自旋锁优缺点

优点 在于,因为自旋锁不会引起调用者睡眠,所以不会进行线程调度,CPU时间片轮转等耗时操作,所有如果能在很短的时间内获得锁,自旋锁的效率远高于互斥锁
缺点 在于,自旋锁一直占用CPU,他在未获得锁的情况下,一直运行自旋,所以占用着CPU,如果不能在很短的时间内获得锁,这无疑会使CPU效率降低。自旋锁不能实现递归调用。

3. 锁的作用

在编程中,特别是多线程开发者中,来保证共享数据操作的完整性。假如有 ABC三条甚至更多的线程,同时去访问资源,那么读的话是没有问题,要是写的话,就可能出问题,同时修改了某一个数据,这样就破坏的数据的完整性了。

加锁的话,就是同一个时间,只能有一个个线程访问,其他的靠边等待,可以给每个对象都对应于一个可称为"互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。

下篇博客将对锁进行举例并对底层进行分析,敬请期待!

更多内容持续更新

iOS底层探索之多线程(十三)—锁的种类你知多少?相关推荐

  1. iOS底层探索(二) - 写给小白看的Clang编译过程原理

    iOS底层探索(一) - 从零开始认识Clang与LLVM 写在前面 编译器是属于底层知识,在日常开发中少有涉及,但在我的印象中,越接近底层是越需要编程基本功,也是越复杂的.但要想提升技术却始终绕不开 ...

  2. iOS 底层探索篇 —— KVC 底层原理

    iOS 底层探索篇 -- KVC 底层原理 1. Method Swizzling的坑与应用 1.1 method-swizzling 是什么? 1.2 坑点 坑点1:method-swizzling ...

  3. iOS 底层探索 - 消息转发

    一.动态方法解析流程分析 我们在上一章<消息查找>分析到了动态方法解析,为了更好的掌握具体的流程,我们接下来直接进行源码追踪. 我们先来到 _class_resolveMethod 方法, ...

  4. iOS底层探索二(OC 中 alloc 方法 初探)

    前言 相关文章: iOS底层探索一(底层探索方法) iOS底层探索三(内存对齐与calloc分析) iOS底层探索四(isa初探-联合体,位域,内存优化) iOS底层探索五(isa与类的关系) iOS ...

  5. 多线程 循环 锁_大多数人还不清楚的iOS多线程

    你不知道的的 iOS 多线程 程序员用有限的生命去追求无限的知识. 有言在先 首先我不是故意要做标题党的,也不是我要炒冷饭,我只是想换个姿势看多线程,本文大部分内容在分析如何造死锁,奈何功力尚浅,然而 ...

  6. 视频教程-iOS底层原理班(下)/OC对象/关联对象/多线程/内存管理/性能优化-iOS

    iOS底层原理班(下)/OC对象/关联对象/多线程/内存管理/性能优化 小码哥教育CEO,曾开发了2个iOS的流行开源框架(MJRefresh.MJExtension),目前在国内的使用率非常高. 李 ...

  7. iOS底层原理班(下)/OC对象/关联对象/多线程/内存管理/性能优化-李明杰-专题视频课程...

    iOS底层原理班(下)/OC对象/关联对象/多线程/内存管理/性能优化-236人已学习 课程介绍         得遇名师,突飞猛进!iOS培训王者MJ(李明杰)老师精心研发,iOS进阶课程,实用技术 ...

  8. iOS - 多线程的锁

    iOS - 多线程的锁 多线程同时访问同一块资源会造成资源抢夺,容易引发数据错乱和数据安全问题,此时我们需要保证资源同时只有一个线程访问,加锁就是为了解决这个问题. 常用的加锁方式:(性能由差到好) ...

  9. OC底层探索(二十二)八大锁

    OC底层文章汇总 锁的种类 在OC中锁分为互斥锁和自旋锁两种. 互斥锁 用于保护临界区,确保同一时间,只有一条线程能够执行 如果代码中只有一个地方需要加锁,大多都使用 self,这样可以避免单独再创建 ...

  10. iOS 开发中的多线程

    线程.进程 什么是线程.进程   有的人说进程就像是人的脑袋,线程就是脑袋上的头发~~.其实这么比方不算错,但是更简单的来说,用迅雷下载文件,迅雷这个程序就是一个进程,下载的文件就是一个线程,同时下载 ...

最新文章

  1. Android Studio 引入aar文件
  2. 今晚8点免费直播 | 详解知识图谱关键技术与应用案例
  3. 用python画时序图源代码_使用python实现画AR模型时序图
  4. 探秘Tomcat——连接篇
  5. 掩膜区域内像素值_基于颜色空间采样的抠图算法
  6. TCP三次握手(待细研究)
  7. java 参数代替所有类_Java中的常用类
  8. 【计算机视觉】运动目标检测算法文献阅读笔记
  9. Avalanche发布AvalancheGo v1.2.3版本
  10. 2021年中国成人商店市场趋势报告、技术动态创新及2027年市场预测
  11. numpy—np.argpartition
  12. 315.计算右侧小于当前元素的个数
  13. 2、linux系统root用户忘记密码后的重置方式
  14. 桌面计算机怎么设置声音,右下角小喇叭不见了-电脑桌面右下角有一个调整声音的小喇叭图标没 – 手机爱问...
  15. VS2008下载地址和版本破解
  16. hdu5510Bazinga
  17. 记一次腾讯IEG面试失败经历
  18. 【输出一个静态“心形”图案、一个跳动的“心”——使用C++、C语言来实现】
  19. 《程序员的自我修养》阅读笔记(一)
  20. Python 最强 IDE 详细使用指南!

热门文章

  1. 让我们一起ML吧(一)聚类分析
  2. 在移动端H5开发中(关于安卓端position:fixed和position:absolute;和虚拟键盘冲突的问题,以及解决方案)...
  3. redis配置认证密码以及远程访问
  4. 写一简单kernel心得
  5. Android项目开发填坑记-so文件引发的攻坚战
  6. win7_fedora 双系统安装方法
  7. 数字金额转为大写金额(C#)
  8. wow和scrollreveal动画
  9. python实训day7
  10. Vue项目按需打包Lodash