线程同步

性能从高到低排序:

os_unfair_lock

示例代码:

#import <os/lock.h>

@property (nonatomic, assign) os_unfair_lock lock;

// 初始化
_lock = OS_UNFAIR_LOCK_INIT;

// 加锁
os_unfair_lock_lock(&_lock);

// 解锁
os_unfair_lock_unlock(&_lock);

// 尝试加锁解锁
if (os_unfair_lock_trylock(&_lock)) {
    os_unfair_lock_unlock(&_lock);
}

OSSpinLock

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

示例代码:

#import <libkern/OSAtomic.h>

@property (nonatomic, assign) OSSpinLock lock;

// 初始化
_lock = OS_SPINLOCK_INIT;

// 加锁
OSSpinLockLock(&_lock);

// 解锁
OSSpinLockUnlock(&_lock);

// 尝试加锁解锁
if (OSSpinLockTry(&_lock)) {
    OSSpinLockUnlock(&_lock);
}

dispatch_semaphore

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

示例代码:

@property (nonatomic, strong) dispatch_semaphore_t semaphore;

// 设置信号量最多的数量,也就是最多可以运行的线程的数量
self.semaphore = dispatch_semaphore_create(5);

// 开启多线程
for (int i = 0; i < 20; ++i) {
    [[[NSThread alloc] initWithTarget:self selector:@selector(task) object:nil] start];
}

// 如果信号量>0,信号量-1,继续执行
// 否则,当前线程进入休眠,并等待信号量>0
// 执行结束后,信号量+1
- (void)task {
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);

    dispatch_semaphore_signal(self.semaphore);
}

pthread_mutex

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

示例代码:

#import <pthread.h>

@property (assign, nonatomic) pthread_mutex_t mutex;

// 1. 初始化锁的属性
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
// PTHREAD_MUTEX_NORMAL
// PTHREAD_MUTEX_ERRORCHECK
// PTHREAD_MUTEX_RECURSIVE
// PTHREAD_MUTEX_DEFAULT
pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_DEFAULT);

// 2. 初始化锁
pthread_mutex_init(&_mutex, &mutexattr);
// 或者锁的属性传NULL,默认为PTHREAD_MUTEX_DEFAULT
pthread_mutex_init(&_mutex, NULL);

// 3. 销毁锁的属性
pthread_mutexattr_destroy(&mutexattr);

// 4. 加锁
pthread_mutex_lock(&_mutex);
pthread_mutex_trylock(&_mutex);

// 5. 解锁
pthread_mutex_unlock(&_mutex);

// 6. 销毁锁
pthread_mutex_destroy(&_mutex);

递归锁:允许同一个线程重复加锁

示例代码:

- (void)mutex_1 {
   // 加锁
   pthread_mutex_lock(&_mutex);

   [self mutex_2];
   
   // 解锁
   pthread_mutex_unlock(&_mutex);
}

- (void)mutex_2 {
    // 加锁
    pthread_mutex_lock(&_mutex);
    
    // 解锁
    pthread_mutex_unlock(&_mutex);
}

运行后,会造成死锁

解决方法:设置递归锁

pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);

条件锁:

假设有两条线程的两个任务,第一个任务需要等待第二个任务执行结束才能执行,这时需要条件锁

示例代码:

#import <pthread.h>

@property (assign, nonatomic) pthread_cond_t cond;

// 1. 初始化条件锁
pthread_cond_init(cond, NULL);

// 2. 执行任务
- (void)mission_1 {
    // 加锁
    pthread_mutex_lock(&_mutex);
    
    if (条件判断) {
        // 等待
        pthread_cond_wait(&_cond, &_mutex);
    }

    // 解锁
    pthread_mutex_unlock(&_mutex);
}

- (void)mission_2 {
    // 加锁
    pthread_mutex_lock(&_mutex);

	// 激活等待    
    pthread_cond_signal(&_cond);
    // 或者
    // 激活所有等待
    pthread_cond_broadcast(&_cond);
   
    // 解锁
    pthread_mutex_unlock(&_mutex);
}

// 3. 释放资源
pthread_cond_destroy(&_cond);

dispatch_queue(DISPATCH_QUEUE_SERIAL)

原理:
串行队列的特点是,其中的任务只能一个一个执行,不能同时取出多个任务
将需要执行的任务放入串行队列中,这样多个线程执行任务时,必须在前一个任务执行完毕后,才能执行后一个任务

示例代码:

@property (nonatomic, strong) dispatch_queue_t queue;

self.queue = dispatch_queue_create("queue_label", DISPATCH_QUEUE_SERIAL);

// 开启多线程
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
    [self task];
});
dispatch_async(queue, ^{
    [self task];
});
dispatch_async(queue, ^{
    [self task];
});

// 线程同步
- (void)task {
    dispatch_sync(self.queue, ^{

    });
}

NSLock

基于pthread_mutex的PTHREAD_MUTEX_NORMAL类型的封装

示例代码:

@property (nonatomic, strong) NSLock *lock;

self.lock = [[NSLock alloc] init];

// 加锁
[self.lock lock];

// 解锁
[self.lock unlock];

NSCondition

对pthread_mutex和pthread_cond的封装

示例代码:

@property (nonatomic, strong) NSCondition *condition;

// 1. 初始化
self.condition = [[NSCondition alloc] init];

// 2. 执行任务
- (void)mission_1 {
    // 加锁
    [self.condition lock];
    
    if (等待条件) {
        // 等待
        [self.condition wait];
    }
    
    // 解锁
    [self.condition unlock];
}

- (void)mission_2 {
    // 加锁
    [self.condition lock];
    
    // 激活
    [self.condition signal];
    // 或者
    // 激活所有
    [self.condition broadcast];
   
    // 解锁
    [self.condition unlock];
}

pthread_mutex(recursive)

NSRecursiveLock

基于pthread_mutex的PTHREAD_MUTEX_RECURSIVE(递归锁)类型的封装

使用方法同NSLock

NSConditionLock

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

示例代码:

@property (nonatomic, strong) NSConditionLock *lock;

// 1. 初始化
self.lock = [[NSConditionLock alloc] initWithCondition:1];

// 2. 加锁/解锁
- (void)task_1 {
    // 加锁
    [self.lock lockWhenCondition:1];
    
    // 解锁
    [self.lock unlockWithCondition:2];
}

- (void)task_2 {
    // 加锁
    [self.lock lockWhenCondition:2];
    
    // 解锁
    [self.lock unlockWithCondition:3];
}

- (void)task_3 {
    // 加锁
    [self.lock lockWhenCondition:3];

    // 解锁
    [self.lock unlock];
}

这段代码的执行流程:

  1. 初始化锁并设置加锁条件为1
  2. 三个任务中,仅task_1的加锁条件为1,所以task_1执行并加锁,其他任务因为加锁条件不为1而无法执行(等待)并加锁
  3. task_1执行结束,解锁并设置加锁条件为2
  4. 剩下的两个任务中,仅task_2的加锁条件为2,所以task_2执行并加锁,而task_3继续等待
  5. task_2执行结束,解锁并设置加锁条件为3
  6. 因为task_3的加锁条件为3,所以task_3等待结束并加锁
  7. task_3执行结束,解锁

@synchronized

对pthread_mutex的封装

示例代码:

@synchronized (索引对象) {

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值