美文网首页iOS点点滴滴iOS开发之常用技术点
iOS 多线程3种同步机制,告别数据脏乱差!

iOS 多线程3种同步机制,告别数据脏乱差!

作者: Allan_野草 | 来源:发表于2018-10-17 17:59 被阅读4次

why need sync

在多线程并发的情况下,一个不注意,非常容易因为并发操作数据,导致各种各样的Bug。相信作为一名开发者,应该也遇到过这样的问题。

那么如何能用正确的姿势,在保证不出Bug的前提下,享受多线程带来的效率呢?

3种同步机制

所有的同步方式,根据不同的同步机制,大致可以分3种,分别是:

1、自旋:通过循环,阻塞当前线程,等待一定条件,再跳出循环往下走
2、串行队列:把任务通过队列,扔到一个线程里面执行,都一个线程了就不会有并发问题
3、信号量:线程的睡眠,与唤醒

下面就来了解下它们的工作原理吧,也更方便以后使用起来更加得心应手。

1、自旋

作为一名合格的画手,上图:



当线程1在lock与unlock之间的时候,
线程2走到lock时,会执行原地进行循环,转圈,阻止代码往下走。
这样,线程2与1就不会同时访问到同一片资源,也就不会产生数据不同步问题。

等1访问完了,2就会跳出循环,再进行它自己的数据操作。

2、串行队列

队列很多系统都会有,这种消息队列,会把队列中一个一个任务,放到同一条线程去执行。
把在不同的线程的数据操作任务,通过dispatch到一个队列,再放到一条单线程中执行,实现同步

3、信号量

原理跟自旋类似。只不过是从循环变成线程睡眠sleep。如果把它们两个比喻成过红绿灯的车子,自旋就是红灯时原地打圈,信号量就是红灯停车,等绿灯再通过。

两者相比,
线程的睡眠与唤醒,有额外的空间与时间开销,意味着响应稍慢,但睡眠节省cpu
而自旋,是循环,消耗cpu计算资源,不需要唤醒,意味着响应快,对于app也意味着更加耗电与发热

在iOS中的使用

  • 串行队列
    搜索关键字:dispatch_queue_t,把相要同步操作的代码,dispatch到同一个queue即可

  • 信号量
    搜索关键字:dispatch_semaphore,一个信号一个坑


  • 最简单的NSLock,@synchronized

有几点值得注意的:
1、追求高效的,可以使用读写锁pthread_rwlock,具体用法网上都有,可以支持读并发,写串行。听起来很帅,实际上也很帅
2、为什么很多说使用@synchronized性能会差,会卡,因为@synchronized(对象,有地址就行),一个地址对应一个锁。不管三七二十一任何情况都用@synchronized(self),原本不需要同步的操作,不需要互为原子的操作,都不能进行并发了,导致慢卡。

所以,还是需要不同场景,合理使用@synchronized(obj1/obj2/obj3..)。这几个用于锁的obj,随便new几个就可以了,不需要必须是self

相关文章

  • iOS 多线程3种同步机制,告别数据脏乱差!

    why need sync 在多线程并发的情况下,一个不注意,非常容易因为并发操作数据,导致各种各样的Bug。相信...

  • 起底多线程同步锁(iOS)

    起底多线程同步锁(iOS) 起底多线程同步锁(iOS)

  • iOS多线程--并行开发二

    接上文iOS多线程--并行开发一 4、线程同步 说到多线程就不得不提多线程中的锁机制,多线程操作过程中往往多个线程...

  • iOS 多线程基础

    转自:iOS 多线程基础 - 简书 多线程同步和异步的区别?IOS中如何实现多线程的同步? 异步:可以同时执行多条...

  • iOS面试总结(初级)

    01:iOS推送机制,实现原理02:多线程编程,GCD,锁,同步异步队列03:property 各种关键字,以及...

  • iOS复习之多线程

    关于iOS多线程,你看我就够了iOS多线程--彻底学会多线程使用dispatch_group来进行线程同步 iOS...

  • iOS中的锁

    锁是一种同步机制,用于多线程环境中对资源访问的限制iOS中常见锁的性能对比图(摘自:ibireme): iOS锁的...

  • 02-UI视图

    UI视图内容 UITableView重用机制数据源的多线程操作(数据源同步问题) 事件传递&视图响应 视图显示原理...

  • iOS面试题

    一.UI相关 1.UITableView相关 (1).重用机制 (2).数据源同步问题(多线程下修改数据源) 2....

  • 课程笔记:第3章 UI视图相关面试问题

    UITableView1、重用机制:先从重用池里取2、多线程下数据源同步(删除(主线程)后又加载数据(子线程)):...

网友评论

  • anyoptional:读写锁读和写操作是分开的,读可以共享写却只能独占,一般适用于读比写多的多的情况,如果读写并没有明早区别用互斥锁(pthread_mutex_lock)就好。其次看完你的文章,没有对何时使用锁、锁区的范围怎么控制有所描述,仅仅介绍了几种锁如何能避免多线程脏数据:sweat:
    Allan_野草:首先看得出来有过真读过这篇文章的,作为笔者也是很开心:smile:
    1、关于读写锁和互斥锁如你所说,没有特别的要求, 使用互斥锁就够了。很多时候客户端,对于数据处理是读多于写的,多线程读与读之间,不存在数据不同步的问题,所以不上锁肯定比上锁性能来得要高。
    2、并于其次,从文章出发点,侧重点不在于锁,锁是实现同步的手段之一,更多的讲的是,同步,它是“怎么做到的”,可以通过锁/自旋算法/队列/信号量,根据不同场景,采取不同的手段。偏原理分析向的,关于落地到具体怎么做这点,可能没有你期望的详细教程,这些搜索引擎上面也是有很多好文章的~可以参考一下

本文标题:iOS 多线程3种同步机制,告别数据脏乱差!

本文链接:https://www.haomeiwen.com/subject/fqdrzftx.html