线程同步和iOS中的锁
一、自旋锁(OSSpinLock)

  1. 一直占用cpu,相当于while循环
  2. 已经不被推荐,因为可能会产生优先级反转;

优先级反转

  1. 多任务的调度有许多算法,常见的有FIFO、优先级、时间片轮询、短任务优先;
  2. 系统一般采取混合算法,因为不同进程特点不一样,单一的调度算法不能满足所有的场景;比如短任务算法需要在线程之间的切换消耗 和 任务真正执行的消耗,两者之间平衡,所以,每种调度算法都有自己的缺点和有点,混合算法是最高效的;
  3. 自旋锁在低等级的任务加锁之后占用了高等级任务所需要的资源。根据算法,如果中等级的任务不需要使用到这个被占用的资源,结果就是中等级任务分配的时间可能会多于高等级;
  4. 以上是高等级任务在等待时可以休眠的情况,也就是等待不是很占用cpu,这种情况下只是出现优先级反转,但是如果高优先级任务的等待是忙循环,也就会出现cpu把事件都分配给高级别任务,但是高级别任务又是忙循环,低级别任务无法获取cpu时间,最终就是死循环,系统可能会崩溃;

二、os_unfair_lock

  1. 休眠,不是忙等待,是互斥锁;
  2. iOS10之后才能使用,用于替换自旋锁;

三、pthread_mutex

  1. 跨平台;
  2. 互斥锁,等待属于休眠;
  3. 可以设置类型,有:默认(PTHREAD_MUTEX_NORMAL)、递归所(PTHREAD_MUTEX_RECUSIVE)、错误检查锁(PTHREAD_MUTEX_ERRORCHECK);
  4. normal类型的锁在创建时(pthread_mutex_init(&mutex,0))传空即可,另外两种锁需要使用pthread_mutex_attr_settype来设置;
  5. 需要使用destory进行销毁,attr、condition、mutex都需要销毁;
  6. 递归锁在递归时使用不会造成死锁问题;
  7. 递归锁:允许同一个线程对通一把锁重复加锁,加锁次数和解锁次数对应时才能解锁;
  8. 条件锁:pthread_cond_wait 和 pthread_cond_signal 配合使用;pthread_cond_wait(cond,mutex)会标记cond并解锁mutex,线程进入休眠,并且阻塞代码。当调用pthread_cond_signal(cond)之后,接收到信号后再对mutex进行加锁,然后继续执行代码;
  9. 条件所中的cond并不是类似于if else,而只是一个标记;
  10. 条件所一般用于解决线程以来问题,当一个线程任务的执行需要以来另一个线程任务的执行时使用,条件起到的是标记和传递的作用;
  11. 唤醒一个线程的等待使用pthread_cond_signal,唤醒所有等待的线程则使用广播方法:pthread_cond_broadcast
  12. 条件等待时,调用signal方法发送信号之后,wait方法其实不是只判断一次的,而是循环判断检测,如果这个锁没加锁成功,就继续等待,如果加锁成功就返回,继续执行后面的代码;所以,signal和unlock方法的调用顺序差别不大,只有在两者调用期间出现很大的延时操作时,wait方法会等待很久才加锁成功,继续执行后面代码。总之,逻辑不会受影响,只是时间问题,pthread_mutex内部已经考虑到这种问题,完成了解决方案的实现;

四、自旋锁和互斥锁

  1. step:按行执行代码;si:按行执行汇编代码;
  2. 自旋锁:忙等,相当于while循环,在汇编中的体现是:jne -> 0xxxxxx ,条件成立则跳转到指定地址循环执行;
  3. 互斥锁:等待时休眠,不占用cpu,类似于RunLoop;本质是:syscall,调用系统级别的函数去休眠并等待被唤醒的消息;
  4. OSSpinLoc是自旋锁,os_unfair_lock和pthread_mutex是互斥锁;

五、NSLock、NSRecusiveLock、NSCondition、NSConditionLock

  1. 是对pthread_mutex的封装,封装成了OC对象;

六、串行队列

  1. async和sync决定是否可以开启线程,队列表示任务的执行方式。
  2. 任务是一代码块为最小颗粒,而不是以一行代码为最小颗粒。代码块中的每一行代码默认都是同步执行;
  3. sync表示从队列中取出任务到当前线程执行,async表示从队列中取出任务异步执行。所以,如果sync+serial queue 结果就是:可以将需要同步的任务(抢占资源的任务)添加到同一个queue中然后同步执行,结果就是线程同步成功;

七、dispatch_semaphore

  1. dispatch_semaphore在初始化时需要使用create传入一个最大信号量;
  2. 最大信号量意味着最多又多少条线程可以同时执行,如果是1,那么就类似于串行队列,所以也可以实现线程同步

dispatch_semaphore_wait(semaphore,time)的作用:

  1. 当semaphore>0时,让当前线程直接继续执行,且dispatch_semaphore的值-1;
  2. 当semaphore<=0时,让当前线程阻塞在这句代码中,且让线程休眠等待;
  3. time表示如果需要等待,那么最长等多久需要返回,传now立马进行判断,传forever就一直等;

dispatch_semaphore_signal(semaphore)的作用:

  1. 让semaphore+1;

使用流程:

  1. 比如创建semaphore设置的最大信号量是5,有100个线程会执行到这句代码;
  2. 当第一次进入时,semaphore=5>0,所以就会让当前进入,继续执行并且dispatch_semaphore-1=4;
  3. 假设dispatch_semaphore_wait和dispatch_semaphore_signal之间的代码时耗时操作;
  4. 以此类推,当第五条线程进入之后,semaphore=0,而因为是耗时操作,所以100条线程都会执行到dispatch_semaphore_wait代码;
  5. 从第六条线程开始,因为dispatch_semaphore=0,线程被阻塞,剩余的95条线程如果在耗时操作没有完成之前,也就是没有调用dispatch_semaphore_signal之前,如果执行到dispatch_semaphore_wait,那么都会处于休眠等待的状态;
  6. 当最先进入的线程执行完耗时操作,调用dispatch_semaphore_signal,dispatch_semaphore+1>0,那么第六条线程就会从休眠中唤醒,继续执行后面的代码;
  7. 以此类推…所以当semaphore初始化时设置为1,那么只有一条线程能够访问共享资源,如此便实现了线程同步;

八、@synchronized

  1. 底层仍然是pthread_mutex,是使用的recusive创建的递归锁;
  2. 根据@synchronized(obj){}传入的对象,生成一个和对象对应的一把锁,存入到map表中;
  3. 关键字不能自动提示,因为存在性能问题,不被推荐使用;

九、性能对比


http://www.taodudu.cc/news/show-1912780.html

相关文章:

  • semaphore的几种用法
  • 难道栈空间有缓存?
  • iOS实例、类、元类
  • id和instancetype
  • Advanced Graphics and Animations for iOS Apps
  • ivar和property
  • bound、frame、position、anchorPoint
  • Java、OC、C/C++中的null
  • iOS:Tagged Pointer
  • sqlite3源码调试
  • 红黑树、B树、B+树各自适用的场景
  • 动态库的隐式链接和显示链接
  • iOS:懒加载符号绑定流程
  • 汇编:call和jmp
  • code review的一些思考
  • iOS:fishhook原理分析
  • mach-O文件结构分析
  • 设备唯一标志的解决方案
  • iOS:主流启动优化方案浅析
  • iOS:segment对齐原则
  • HTTP缓存机制及其在iOS中的应用
  • iOS:SideTable
  • iOS:isa指针
  • iOS底层:PAGEZERO的作用
  • iOS图形学(三):屏幕成像原理
  • iOS图形学(四):iOS中的绘图框架
  • Java基础(一):简介和基础数据类型
  • Java基础(二):面向对象
  • Java:常量池
  • Java基础(三):常用对象

iOS中的锁和线程同步相关推荐

  1. Linux线程同步(二)---互斥锁实现线程同步

    一 why 先给自己打个广告,本人的微信公众号:嵌入式Linux江湖,主要关注嵌入式软件开发,股票基金定投,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题. 在博客&l ...

  2. JAVA 中无锁的线程安全整数 AtomicInteger介绍和使用

    转载自 http://blog.csdn.net/bigtree_3721/article/details/51296064 JAVA 中无锁的线程安全整数 AtomicInteger,一个提供原子操 ...

  3. iOS多线程各种安全锁介绍 - 线程同步

    一.atomic介绍 github对应Demo:https://github.com/Master-fd/LockDemo 在iOS中,@property 新增属性时,可以增加atomic选项,ato ...

  4. IOS多线程系统学习之线程同步与线程通信

    多线程编程是有趣的事情,它很容易突然出现"错误情况",这是由于系统的线程调度具有一定的随机性造成的.不过,即使程序偶然出现"错误情况",这是由于系统的线程调度具 ...

  5. python中gil锁和线程锁_Python线程——GIL锁、线程锁(互斥锁)、递归锁(RLock)...

    GIL锁 ​ 计算机有4核,代表着同一时间,可以干4个任务.如果单核cpu的话,我启动10个线程,我看上去也是并发的,因为是执行了上下文的切换,让看上去是并发的.但是单核永远肯定时串行的,它肯定是串行 ...

  6. java 信号量 互斥锁_线程同步(互斥锁与信号量的作用与区别)

    "信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在 哪里).而互斥锁是用在多线程多任务互斥的,一 ...

  7. iOS 中的网络请求 (同步请求、异步请求、GET请求、POST请求)

    1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作, 2.异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然 ...

  8. Python 线程(二):简单锁实现线程同步

    Python中有两种锁,一个锁是原始的锁(原语), 不可重入,而另一种锁则是可重入的锁即递归锁.而是thread模块中,只提供了不可重入的锁,而在threading中则提供这两种锁. 可重入:当一个线 ...

  9. python中gil锁和线程锁_浅谈Python中的全局锁(GIL)问题

    CPU-bound(计算密集型) 和I/O bound(I/O密集型) 计算密集型任务(CPU-bound) 的特点是要进行大量的计算,占据着主要的任务,消耗CPU资源,一直处于满负荷状态.比如复杂的 ...

  10. iOS中安全结束 子线程 的方法

    一个典型的结束子线程的方法:   用 isFinished 检测子线程是否被完全kill掉 -(IBAction)btnBack:(id)sender {//释放内存 仅仅remove 并不会触发内存 ...

最新文章

  1. tomcat 多实例启动脚本
  2. centos在线安装svn
  3. C51 汇编 双层循环延时代码
  4. 深度学习之 Cascade R-CNN
  5. pip与conda简述
  6. Intel Core Enhanced Core架构/微架构/流水线 (3) - 流水线概述
  7. 那些除夕夜还在上BOSS直聘的人
  8. Pytorch的可视化工具tensorboardX
  9. uoml文档交换服务器,文档处理系统和方法
  10. Android成企业安全主要威胁的十大原因
  11. Android 手机做麦克风扩音器demo
  12. 各个地图经纬度转换工具类
  13. 计算机程序ppt,计算机和计算机程序.ppt
  14. 通达信接口官网与量化交易有联系吗?
  15. Hexo个人博客搭建教程
  16. 黑名单挂断电话及删除电话记录
  17. 易语言 上传文件到远程服务器,易语言与向远程服务器发送文件夹
  18. Nginx反向代理的两种配置方式
  19. 基金定投是什么?定投的特点?
  20. 【Mo 人工智能技术博客】图卷积网络概述及其在论文分类上的应用

热门文章

  1. SpringCloud OpenFeign(二)
  2. mysql中like,limit,union及union all查询
  3. Redis主从架构和哨兵架构模式
  4. 一行数据中三列值的比较
  5. 2018.09.14python学习第四天part3
  6. 加速与缓存技术之Varnish
  7. Swift 数据类型(三)
  8. 利用 /dev/zero 创建虚拟硬盘
  9. winform datagridview 打印预览
  10. 如何远程配置DHCP服务器