zoukankan      html  css  js  c++  java
  • OC原理之多线程中的锁(一)

    OSSpinLock

    OSSpinLock叫做"自旋锁",等待锁的线程会处于忙等状态,一直占用着cpu资源。由于可能会出现优先级反转的问题,是个不安全锁。在iOS10苹果已经不推荐使用了

    优先级反转问题

    如果等待锁的线程优先级较高,它会一直占用着CPU资源,优先级低的线程就无法释放 使用的时候需要导入#import <libkern/OSAtomic.h>

    使用代码

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

    os_unfair_lock

    os_unfair_lock用于取代不安全的OSSpinLock,iOS10以后才支持

    相比较于OSSpinLock的区别,等待os_unfair_lock锁的线程会处于休眠状态,并非忙等

    使用时,如要导入头文件#import <os/lock.h>

    使用代码

    os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
    bool result = os_unfair_lock_trylock(&lock); // 尝试加锁 返回值=是否加锁成功
    os_unfair_lock_lock(&lock); // 加锁
    os_unfair_lock_unlock(&lock); // 解锁

    pthread_mutex

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

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

    使用代码

    // 初始化锁的属性
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
        
    // 初始化锁
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, &attr);
        
    // 尝试加锁
    bool result = pthread_mutex_trylock(&mutex);
        
    // 加锁
    pthread_mutex_lock(&mutex);
        
    // 解锁
    pthread_mutex_unlock(&mutex);
        
    // 销毁相关资源
    pthread_mutexattr_destroy(&attr);
    pthread_mutex_destroy(&mutex);

    pthread_mutex - 递归锁

    递归锁的话,创建方式与互斥锁的方式相同,只是在创建pthread_mutexattr_t的之后,设置类型为PTHREAD_MUTEX_RECURSIVE

    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

    pthread_mutex – 条件

    使用代码:

    // 初始化锁
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, NULL);
        
    // 初始化条件
    pthread_cond_t condition;
    pthread_cond_init(&condition, NULL);
        
    // 等待条件(进入休眠,放开mutex锁,被唤醒后,会再次对mutex加锁)
    pthread_cond_wait(&condition, &mutex);
    // 激活一个等待该条件的线程
    pthread_cond_signal(&condition);
    // 激活所有等待该条件的线程
    pthread_cond_broadcast(&condition);
        
    // 销毁
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&condition);

    NSLock

    NSLock是对mutex普通锁的封装

    NSRecursiveLock

    NSrecursiveLock是对mutex递归锁的封装

    NSCondition

    NSCondition是对mutex和cond的封装

    dispatch_semaphore

    semaphore叫做"信号量"

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

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

    使用代码:

    // 信号量的初始值
    int value = 1;
    // 初始化信号量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(value);
    // 如果信号量的值<=0,当前线程就会进入休眠等待(知道信号量的值>0)
    // 如果信号量的值>0,就减1,然后往下执行后面的代码
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    // 让信号量的值加1
    dispatch_semaphore_signal(semaphore);

    dispatch_queue

    直接使用GCD的串行队列,也是可以显示线程同步的

    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
            
    });

    @synchronized

    @synchronized是对mutex递归锁的封装

    源码查看:objc4中的objc-sync.mm文件

    @synchronized(obj)内部会生成obj对应的递归锁,然后进行加锁、解锁操作

    使用代码:

    @synchronized (object) {
            
    }
  • 相关阅读:
    LearnMoreStudyLess《如何高效学习》斯科特.杨
    Asp.net 生成多个Excel打包zip进行下载(建立在Aspose.Cells.dll生成Excel,建立在ICSharpCode.SharpZipLib.dll打包zip)
    【面经】美团测试1,2,3面,一起来聊聊?
    【python】面试高频:浅拷贝 vs 深拷贝、'==' vs 'is'
    【图解Http 学习摘要】五、HTTPS 中的加密、证书介绍,不一直使用 HTTPS 的原因
    【图解Http 学习摘要】四、HTTP 缺点
    【图解Http 学习摘要】三、HTTP 协议基础、四次挥手
    【图解Http 学习摘要】二、IP,TCP 和 DNS、三次握手
    【图解Http 学习摘要】一、http介绍、TCP/IP 协议族
    【杂谈】关于常见架构的整理,单应用、微服务、SOA、分布式和集群
  • 原文地址:https://www.cnblogs.com/muzichenyu/p/14443835.html
Copyright © 2011-2022 走看看