• 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) {
            
    }
  • 相关阅读:
    LeetCode Path Sum II
    LeetCode Longest Palindromic Substring
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Binary Tree Maximum Path Sum
    LeetCode Find Peak Element
    LeetCode Maximum Product Subarray
    LeetCode Intersection of Two Linked Lists
    一天一个设计模式(1)——工厂模式
    PHP迭代器 Iterator
  • 原文地址:https://www.cnblogs.com/muzichenyu/p/14443835.html
Copyright © 2020-2023  润新知