iOS底层探索之多线程(十六)——锁分析(NSLock、NSCondtion、NSRecursiveLock、NSCondition)
iOS 开发,各种锁你了解多少?NSLock、NSCondtion、NSRecursiveLock…
回顾
在之前的一篇博客中,介绍了锁的种类,在上一篇博客中已经对@synchronized
锁进行了源码分析,还有其他的一些锁没有介绍,那么本篇博客就分析一下其他的一些锁!
iOS底层探索之多线程(一)—进程和线程
iOS底层探索之多线程(二)—线程和锁
iOS底层探索之多线程(三)—初识GCD
iOS底层探索之多线程(四)—GCD的队列
iOS底层探索之多线程(五)—GCD不同队列源码分析
iOS底层探索之多线程(六)—GCD源码分析(sync 同步函数、async 异步函数)
iOS底层探索之多线程(七)—GCD源码分析(死锁的原因)
iOS底层探索之多线程(八)—GCD源码分析(函数的同步性、异步性、单例)
iOS底层探索之多线程(九)—GCD源码分析(栅栏函数)
iOS底层探索之多线程(十)—GCD源码分析( 信号量)
iOS底层探索之多线程(十一)—GCD源码分析(调度组)
iOS底层探索之多线程(十二)—GCD源码分析(事件源)
iOS底层探索之多线程(十三)—锁的种类你知多少?
iOS底层探索之多线程(十四)—关于@synchronized锁你了解多少?
iOS底层探索之多线程(十五)—@synchronized源码分析
1. 关于锁的介绍
1.1 锁的分类
⾃旋锁
:线程反复检查锁变量是否可⽤。由于线程在这⼀过程中保持执⾏,因此是⼀种忙等待
。⼀旦获取了⾃旋锁
,线程会⼀直保持该锁,直⾄显式释放⾃旋锁。⾃旋锁
避免了进程上下⽂的调度开销,因此对于线程只会阻塞很短时间的场合是有效的。互斥锁
:是⼀种⽤于多线程编程中,防⽌两条线程同时对同⼀公共资源(⽐如全局变量)进⾏读写
的机制。该⽬的通过将代码切⽚成⼀个⼀个的临界区⽽达成互斥
的作用。
属于互斥锁的有:NSLock 、pthread_mutex 、 @synchronized等
1.2 锁的归类
条件锁
:就是条件变量,当进程的某些资源要求不满⾜时就进⼊休眠,也就是锁住了。当资源被分配到了,条件锁打开,进程继续运⾏,如:NSCondition
、NSConditionLock
递归锁
:就是同⼀个线程可以加锁N次⽽不会引发死锁,如:NSRecursiveLock
、pthread_mutex(recursive)
信号量(semaphore)
:是⼀种更⾼级的同步机制,互斥锁可以说是semaphore
在仅取值0/1
时的特例。信号量可以有更多的取值空间,⽤来实现更加复杂的同步
,⽽不单单是线程间互斥
,如:dispatch_semaphore
锁的归类其实基本的锁就包括了三类: ⾃旋锁
互斥锁
读写锁
,其他的⽐如条件锁
,递归锁
,信号量
都是上层的封装和实现!
读写锁
:读写锁实际是⼀种特殊的互斥锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进⾏读访问,写者则需要对共享资源进⾏写操作。
2. NSLock
- 举例1
有如下代码:
- (void)is_crash{NSLog(@"reno");for (int i = 0; i < 10000; i++) {dispatch_async(dispatch_get_global_queue(0, 0), ^{_testArray = [NSMutableArray array];});}
}
- 不加锁的时候运行
没有加锁,多线程访问,直接奔溃了,那么现在去加锁看看结果如何呢?
- 加锁
加锁的情况下,就不会奔溃,保证了线程的安全。
- 举例 2
NSLog(@"jpreno");
dispatch_async(dispatch_get_global_queue(0, 0), ^{static void (^testMethod)(int);testMethod = ^(int value){if (value > 0) {NSLog(@"current value = %d",value);testMethod(value - 1);}};testMethod(10);});
- 打印结果
打印结果没有任何问题,那么加个 for
循环呢?
现在出现了,打印的数据混乱了,也就是多线程访问了,那么解决办法,就是加锁
,那么加在哪里呢?大部分人会加在这里,如下:
那么加在上图中,会正常打印吗?现在还不得而知,现在我们去运行一下代码来看看吧!
从运行打印结果来看,数据还是错乱了,很显然NSLock
的锁的位置没有加对地方,那么正确✅的加锁位置在哪里呢?请看
iOS底层探索之多线程(十六)——锁分析(NSLock、NSCondtion、NSRecursiveLock、NSCondition)相关推荐
- iOS底层探索二(OC 中 alloc 方法 初探)
前言 相关文章: iOS底层探索一(底层探索方法) iOS底层探索三(内存对齐与calloc分析) iOS底层探索四(isa初探-联合体,位域,内存优化) iOS底层探索五(isa与类的关系) iOS ...
- ROS探索总结(十六)(十七)(十八)(十九)——HRMRP机器人的设计 构建完整的机器人应用系统 重读tf 如何配置机器人的导航功能
ROS探索总结(十六)--HRMRP机器人的设计 1. HRMRP简介 HRMRP(Hybrid Real-time Mobile Robot Platform,混合实时移动机器人平台 ...
- iOS 底层探索篇 —— KVC 底层原理
iOS 底层探索篇 -- KVC 底层原理 1. Method Swizzling的坑与应用 1.1 method-swizzling 是什么? 1.2 坑点 坑点1:method-swizzling ...
- IOS音视频(四十六)离线在线语音识别方案
IOS音视频(四十六)离线在线语音识别方案 IOS音视频(四十六)离线在线语音识别方案 方案一:Siri语音识别 Siri语音识别简介 Siri语音识别功能类介绍 Siri语音识别功能集成 方案二:百 ...
- iOS 11开发教程(十六)iOS11应用视图之删除空白视图
iOS 11开发教程(十六)iOS11应用视图之删除空白视图 当开发者不再需要主视图的某一视图时,可以将该视图删除.实现此功能需要使用到removeFromSuperview()方法,其语法形式如下: ...
- iOS底层探索(二) - 写给小白看的Clang编译过程原理
iOS底层探索(一) - 从零开始认识Clang与LLVM 写在前面 编译器是属于底层知识,在日常开发中少有涉及,但在我的印象中,越接近底层是越需要编程基本功,也是越复杂的.但要想提升技术却始终绕不开 ...
- iOS 底层探索 - 消息转发
一.动态方法解析流程分析 我们在上一章<消息查找>分析到了动态方法解析,为了更好的掌握具体的流程,我们接下来直接进行源码追踪. 我们先来到 _class_resolveMethod 方法, ...
- 统计学简介之十六——单因素方差分析
统计学简介之十六--单因素方差分析 一.数据结构 二.分析步骤 2.1 提出假设 2.2 构造检验的统计量 2.3 统计决策 2.4 方差分析表
- 【软件开发底层知识修炼】十六 快速学习GDB调试三 使用GDB的数据断点监测变量是否改变
上一篇文章我们学习了如何使用GDB进行软件断点调试和硬件断点调试:[软件开发底层知识修炼]十五 快速学习GDB调试二 使用GDB进行断点调试 本篇文章继续上一篇文章的学习,如何使用GDB的数据断点监测 ...
- ios基础篇(二十六)—— UITableViewCell的分组索引与标记
一.表视图的索引目录 首先要创建一个TableView,之前有说过,这里就不详细说了(参考前面第十四篇). 直接贴代码吧, 1 #import "ViewController.h" ...
最新文章
- python 大量网络请求_大规模异步新闻爬虫之网络请求函数的优化
- LIstview滑动时不加载图片,停止时加载!
- Spark性能优化:资源调优篇
- 东哥读书小记 之 《一个广告人的自白》
- 考研总分多少能去辽师_辽宁师范大学在职研究生统考分数到达到多少呢统考通过就会被录取吗...
- 跨平台APP----对Cordova,APPCan,DCloud,APICloud四大平台的分析
- Linux下PS命令详解 (转)
- UI自动化测试之iframe切换
- .ftl文件简介及语法
- c++设计地铁售票系统_地铁自动售票机中票务系统的设计与开发
- 微软kinect的五个非游戏的应用
- H5小游戏《看你有多色》扩展(辅助、眼力)
- latex-多个表格引用
- Flash在线编程构件的使用
- 【Linux】git clone报错fatal: unable to access ‘https://github.com/xxx.git/‘: Encountered end of file
- 关于ant design table加scroll属性后列跟表头不对齐
- 学术诚信的重要性_增强学术诚信意识,弘扬严谨学风
- BIOS入门基础------ACPI
- 上传csv文件后出现乱码
- Scratch(三十七):串联电路