iOS中的锁笔记

2020-11-28  本文已影响0人  会跑的鱼_09

本文只是我对iOS中锁的学习笔记,没有太深入的研究讲解。先来一张ios中常用锁的性能对照图


截屏2020-11-25 下午5.07.12.png

锁的分类

自旋锁:在未获取到锁的情况下,线程会反复检查锁变量是否可用,处于一直忙等状态,所以不会进行上下文切换,适用于阻塞很短时间的场景,常见的锁有OSSpinLock,另外atomic修饰符内部也是使用的自旋锁。

互斥锁:是一种用于多线程编程中,防止两条线程同时对同一公共资源(比 如全局变量)进行读写的机制。它可以将代码切片成一个一个的临界区以达到锁的目的。拿不到锁的线程会进入睡眠状态,等待其他线程释放锁后将其唤醒。NSLock、pthread_mutex、@synchronized都属于互斥锁。

OSSpinLock(自旋锁)

由于多线程优先级反转问题,可能导致优先级高的线程一直处于忙等状态,而优化级低的线程又拿不到锁,所以ios10开始已被os_unfair_lock取代。

dispatch_semaphore

一种比较高级的线程间同步机制,互斥锁可以说是semaphore在仅取值0/1时的特例。

pthread_mutex、NSLock、NSRecursiveLock

NSLock和NSRecursiveLock都是基于pthread_mutex互斥锁实现,但NSRecursiveLock支持递归调用。

NSCondition、NSConditionLock

其底层是使用的互斥锁,但在此基础上增加了线程间通讯的能力,通过相应的api可以控制线程的执行流程。

synchronized分析

被@synchronized包裹的代码块会被编译器转换成objc_sync_enter和objc_sync_exit,并且在加解锁时是操作的SyncData这个对象

typedef struct alignas(CacheLineSize) SyncData {
    struct SyncData* nextData;
    DisguisedPtr<objc_object> object;
    int32_t threadCount;  // number of THREADS using this block
    recursive_mutex_t mutex;
} SyncData;

SyncData存储在线程缓存中,是一个链表,主要用于针对不同对象加锁的情况。另外其中threadCount是用于多线程的场景,如果多个线程对同一个对象加锁,只会增加threadCount的值。如果是同一个线程对同一对象多次加锁,例如嵌套的情况,那么会操作线程缓存中的lockCount变量。

推荐学习:
iOS-底层原理 29:锁的原理

上一篇 下一篇

猜你喜欢

热点阅读