美文网首页
底层21:多线程-锁

底层21:多线程-锁

作者: 张无奈 | 来源:发表于2020-09-09 22:00 被阅读0次

    iOS中的线程同步方案:

    1.OSSpinLock:

    叫做“自旋锁”,等待锁的线程会处于忙等(busy-wait)状态,一直占用CPU资源

    目前已经不再安全,可能会出现优先级反转问题(ios10之后就不适用)。

    如果等待它的线程优先级比较高,他会一直占用着CPU资源,优先级低的线程就无法释放锁。

    导入头文件#import <libkern/OSAtomic.h>

    OSSpinLock lock = OS_SPINLOCK_INIT; //初始化

    bool result = OSSpinLockTry(&lock); //尝试加锁(如果需要等待就不加锁,直接返回false;如果不需要等待就加锁,返回true)

    OSSpinLockLock(&lock); //加锁

    OSSpinLockUnlock(&lock); //解锁

      1)引入头文件:#import <libkern/OSAtomic.h>

      2)定义全局变量,初始化:

      3)使用加锁解锁

    存钱取钱加锁实现:

    2.os_unfair_lock

    os_unfair_lock用于取代不安全的OSSpinLock,从iOS10开始才支持。

    从底层调用看,等待os_unfair_lock锁的线程会处于休眠状态并非忙等

    需要导入头文件#import <os/lock.h>

    属于低级锁 low-level-lock 

    (个人理解:从底层一步一步走,发现它会进入休眠,所以属于互斥锁)

    3.pthread_mutex

    mutex叫做“互斥锁”,等待锁的线程会处于休眠状态。

    需要导入头文件#import <pthread.h>

    默认属性PTHREAD_MUTEX_DEFAULT是默认锁,换成PTHREAD_MUTEX_RECURSIVE为递归锁

    递归锁:允许同一个线程对一把锁进行重复加锁

    pthread_mutex-条件:多线程相互依赖的场景可能会使用(生产者、消费者模式)

    4.dispatch_semaphore

    semaphore叫做“信号量”

    信号量的初始值,可以用来控制线程并发访问的最大数量。

    信号量的初始值为1,代表同时只允许1条线程访问资源,保证线程同步。

    5.dispatch_queue(DISPATCH_QUEUE_SERIAL)

    直接使用GCD的串行队列,也可以实现线程同步。

    6.NSLOCK

      是对mutex普通锁的封装

    7.NSRecursiveLock

      NSRecursiveLock也是对mutex递归锁对封装,API跟NSLock基本一致。

    8.NSCondition

    NSCondition是对mutex和cond的封装。

    9.NSConditionLock

    NSConditionLock是对NSCondition的进一步封装,可以设置具体的条件值。

    这样可以设置让线程之间依赖

    10.@synchronized

    性能从高到低:推荐使用dispatch_semaphore、pthread_mutex

    自旋锁、互斥锁比较

    什么时候使用自旋锁比较好?

    预计线程等待锁的时间很短;

    加锁的代码(临界区(lock与unlock之间))经常被调用,但竞争情况很少发生;

    CPU资源不紧张;

    多核处理器;

    什么时候使用互斥锁比较好?

    预计线程等待锁的时间较长;

    单核处理器;

    临界区有IO操作(文件操作);

    临界区代码复制或者循环量大;

    临界区竞争非常激烈;

    相关文章

      网友评论

          本文标题:底层21:多线程-锁

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