美文网首页iOS
OC中的线程锁

OC中的线程锁

作者: 我是繁星 | 来源:发表于2018-07-21 11:20 被阅读17次

    下面是各种线程锁的效率,当然这个结果只能当做一个定性分析,根据实现原理的不用,这些形形色色的锁再不同场景下可以发挥其独有的作用。

    摘自YY大神.png
    自旋锁:当一个线程上锁之后,其他线程再次访问会一直循环查看该锁是否被释放,因为忙等会消耗大量CPU资源,但是不涉及到操作系统上下文的切换,所以该锁适用于锁的持有者保存时间较短的情况,例如内存缓存的存取。

    解释:

    线程一直running(加锁-->解锁),死循环(do-while等待)检测锁的标志位,机制比较简单。也正因为do-while所以会占用CPU时间,消耗CPU资源较多。

    由于OSSpinLock存在优先级反转的问题,也就是低优先级的线程1获得锁并访问共享资源,高优先级的线程2也想访问共享资源,则线程2处于自旋锁忙等状态从而占用大量CPU资源,而低优先级线程无法与高优先级线程争夺CPU资源,导致线程1迟迟不能完成。所以苹果又出了个os_unfair_lock_t
    详见YY大神 不再安全的 OSSpinLock

    用法:

    os_unfair_lock_t lock = &(OS_UNFAIR_LOCK_INIT);
    os_unfair_lock_lock(lock);
    os_unfair_lock_unlock(lock);
    

    原理:(伪代码如下)

    bool lock = false;
    do{  
          while(lock);//如果上锁循环等待。这里lock的存取是具有原子性的。
          lock = true;//上锁
          Critical section//临界区,需要保护的代码。
          lock = false;//解锁
          Reminder section // 不需要锁保护的代码
    }
    
    信号量(dispatch_semaphore):当信号量值大于0,该函数所处线程就继续执行下面的语句,当信号量值小于0,会阻塞当前线程。相关方法:dispatch_semaphore_wait(-1)、dispatch_semaphore_signal(+1)。
    解释:

    当dispatch_semaphore_wait判断小于0的时候,当前线程会主动让出时间片,由于让出时间片会导致操作系统切到其他线程,这种上下文切换通常需要10微秒的时间,而且至少要切换两次。所以等待时间短频繁切换的情况下他并不适用。

    pthread_mutex:互斥锁的实现原理和信号量非常相似,不用忙等,而是阻塞线程,需要上下文切换。
    解释:

    存在三种类型 PTHREAD_MUTEX_NORMALPTHREAD_MUTEX_ERRORCHECKPTHREAD_MUTEX_RECURSIVE等等,这也是为什么它的性能相比于信号量略低。

    使用:
    #import <pthread.h>//引用
    pthread_mutex_t pMutex;//申明
    pthread_mutex_init(&pMutex,NULL);//初始化
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);  // 定义锁的属性、有很多种类型,如递归锁等
    pthread_mutex_lock(&pMutex);//获得锁
    pthread_mutex_unlock(&pMutex);//解锁
    

    相关文章

      网友评论

        本文标题:OC中的线程锁

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