美文网首页
多线程 (锁)学习

多线程 (锁)学习

作者: Tony17 | 来源:发表于2020-02-28 08:59 被阅读0次

前言

多线程在开发过程中使用非常频繁,但是由于 OC GCD的强大和客户端对于多线程的需求没有那么复杂。很多时候就是一个简单的调用就可以满足我们的需求,但是随着项目的增大,简单的开启异步线程已经不能瞒住我们的需要。今天我来简单学些一下多线程的知识。

多线程

thread_all.png

同步,异步,并发,串行

  • 同步和异步的主要影响: 能不能开启新的线程
    • 同步: 在当前线程中执行任务,不具备开启新线程的能力
    • 异步: 在新的线程中执行任务,具备开启新线程的能力
  • 并发和串行的主要影响: 任务的执行方式
    • 并发: 多个任务同时执行,只有在异步函数下才有效
    • 串行: 一个任务执行完毕后,开始执行下一个任务
thread_sync_async.png

多线程隐患

多线程最常见的隐患是资源共享,当多个线程同时访问同一块资源的时候,容易引发数据错乱和数据安全问题。
解决办法是线程同步技术,实现同时只会有一个线程访问资源已解决资源共享的问题。
最常见的线程同步技术是 加锁

线程同步方案

以下说明按照性能从高到低排序:

  • os_unfair_lock
    • 用于取代不安全的 OSSpinLock,从iOS 10才开始支持
    • 属于互斥锁,会让等待锁的线程处于休眠状态,并非忙等
    • 需要导入头文件 <os/lock.h>
  • OSSpinLock
    • 自旋锁,等待锁的线程会处于忙等状态,一直占用CPU资源
    • 已经不再安全,会出现优先级反转导致死锁问题
    • 需要导入头文件 <libkern/OSAtomic.h>
  • dispatch_semaphore
    • 信号量,初始值可以控制线程并发访问的最大数量
    • 如果初始值为1,代表同时只能有1个线程访问资源,保持同步
  • pthread_mutex
    • 互斥锁,等待锁的线程会处于休眠状态
    • 需要导入头文件 <pthread.h>
    • 递归锁也是通过互斥锁实现的
    • 通过设置不同的属性值,实现不同类型的锁 PTHREAD_MUTEX_RECURSIVE 就是递归锁
  • dispatch_queue(DISPATCH_QUEUE_SERIAL)
    • GCD串行队列,可以实现锁的功能
  • NSLock
    • 对 mutex 普通锁的封装
  • NSCondition
    • 对 mutex 和 cond 的封装
  • pthread_mutex(recursive)
    • 递归锁
  • NSRecursiveLock
    • 对 mutex 递归锁的封装,API 跟 NSLock 基本一致
  • NSConditionLock
    • NSCondition 进一步的封装
  • @synchronized
    • 对 mutex 递归锁的封装
    • @synchronized(obj) 内部会生成 obj 对应的递归锁,然后进行加锁,解锁操作

属性的 atomic 修饰符用于保证属性的 setter、getter 的原子性操作,相当于在 getter、setter 内部价了线程同步的锁,但是它并不能保证使用属性的过程中是线程安全的

互斥锁,自旋锁比较

  • 什么时候选用自旋锁比较划算
    • 预计线程等待锁的时间很短
    • 加锁代码(临界区)经常被调用,但竞争很少发生
    • CPU 资源不紧张
    • 多核处理器
  • 什么时候选用互斥锁比较划算
    • 预计线程等待时间比较长
    • 单核处理器
    • 临界区有 IO 操作
    • 临界区代码复杂或者循环量大
    • 临界区竞争非常激烈
    • 递归锁是特殊的互斥锁,允许同一线程重复加锁

iOS中的读写安全方案

典型的应用场景是多读单写,经常用于文件等数据的读写操作,iOS中的实现方案有:

  • pthread_rwlock:读写锁
    • 等待锁的线程会进入睡眠
  • dispatch_barrier_async:异步栅栏调用
    • 必须传入自己创建的并发队列
    • 如果传入一个串行队列或者全局的并发队列,这个函数的效果相当于 dispatch_async 函数

最后

以上就是本篇的内容,势必会有一些遗漏和错误,欢迎斧正~

相关文章

  • iOS开发底层相关基础知识点

    正确使用多线程同步锁@synchronized() YYKit学习笔记

  • 【python】多线程(高级篇)

    多线程互斥锁 关于如何使用Lock( 锁 ) 【目标】学习如何加锁,获取钥匙,释放锁. 语句如下: 【注释】loc...

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

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

  • 多线程 (锁)学习

    前言 多线程在开发过程中使用非常频繁,但是由于 OC GCD的强大和客户端对于多线程的需求没有那么复杂。很多时候就...

  • Redis实现分布式锁

    什么是分布式锁 在学习Java多线程编程的时候,锁是一个很重要也很基础的概念,锁可以看成是多线程情况下访问共享资源...

  • 如何优雅地用Redis实现分布式锁?

    什么是分布式锁 在学习Java多线程编程的时候,锁是一个很重要也很基础的概念,锁可以看成是多线程情况下访问共享资源...

  • 锁的优化

    在前几天的文章:浅谈Java中的锁:Synchronized、重入锁、读写锁 中我们学习了多线程环境下为了保证线程...

  • Java面试:多线程中的各种锁,你了解几个?

    学习 java 多线程时,最头疼的知识点之一就是 java 中的锁了,什么互斥锁、排它锁、自旋锁、死锁、活锁等等,...

  • JUC学习笔记三

    JUC学习笔记三 用于解决多线程同步问题的方式 隐式锁(synchronized) 同步代码块 同步方法 显式锁(...

  • 浅析乐观锁、悲观锁与CAS

    乐观锁与悲观锁 处理多线程并发访问最常用的就是加锁,锁又分成乐观锁和悲观锁。 悲观锁 在多线程访问共享资源时,同时...

网友评论

      本文标题:多线程 (锁)学习

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