OC-Lock

作者: xiaofu666 | 来源:发表于2021-09-06 16:36 被阅读0次
  1. OSSpinLock 自旋锁 (忙等)
@property (assign, nonatomic) OSSpinLock lock;
    OSSpinLockLock(&_ lock);
    //code
    OSSpinLockUnlock(&_ lock);
  1. os_unfair_lock 互斥锁
@property (assign, nonatomic) os_unfair_lock lock;
    os_unfair_lock_lock(&_ lock);
    //code
    os_unfair_lock_unlock(&_ lock);
  1. pthread_mutex_t 跨平台通用
@property (assign, nonatomic) pthread_mutex_t lock;
    // 初始化属性
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    // PTHREAD_MUTEX_DEFAULT         互斥锁
    // PTHREAD_MUTEX_RECURSIVE       递归锁
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
    // 初始化锁
    pthread_mutex_init(&_lock, &attr);
    // 销毁属性
    pthread_mutexattr_destroy(&attr);
    pthread_mutex_lock(&_ lock);
    //code
    pthread_mutex_unlock(&_ lock);
- (void)dealloc{
    pthread_mutex_destroy(& lock);
}

PTHREAD_MUTEX_RECURSIVE 递归锁:允许同一个线程对一把锁进行重复加锁
PTHREAD_MUTEX_DEFAULT 互斥锁:每次只能加一把锁,循环加锁会变成死锁

  1. pthread_cond_init
@property (assign, nonatomic) pthread_mutex_t mutex;
@property (assign, nonatomic) pthread_cond_t cond;
    // 初始化属性
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    // 初始化锁
    pthread_mutex_init(&_mutex, &attr);
    // 销毁属性
    pthread_mutexattr_destroy(&attr);
    // 初始化条件
    pthread_cond_init(&_cond, NULL);
    [[[NSThread alloc] initWithTarget:self selector:@selector(__remove) object:nil] start];
    
    [[[NSThread alloc] initWithTarget:self selector:@selector(__add) object:nil] start];
// 删除数组中的元素
- (void)__remove
{
    pthread_mutex_lock(&_mutex);
    NSLog(@"__remove - begin");
    
    if (self.data.count == 0) {
        // 等待,直到收到信号,才会继续执行
        pthread_cond_wait(&_cond, &_mutex);
    }
    
    [self.data removeLastObject];
    NSLog(@"删除了元素");
    
    pthread_mutex_unlock(&_mutex);
}

// 线程2
// 往数组中添加元素
- (void)__add
{
    pthread_mutex_lock(&_mutex);
    
    sleep(1);
    
    [self.data addObject:@"Test"];
    NSLog(@"添加了元素");
    
    // 信号
    pthread_cond_signal(&_cond);
    // 广播
//    pthread_cond_broadcast(&_cond);
    
    pthread_mutex_unlock(&_mutex);
}
- (void)dealloc
{
    pthread_mutex_destroy(&_mutex);
    pthread_cond_destroy(&_cond);
}
  1. NSLock 是对pthread_mutex_tPTHREAD_MUTEX_DEFAULT的OC封装
@property (strong, nonatomic) NSLock *lock;
self.lock = [[NSLock alloc] init];
    [self. lock lock];
    //code
    [self. lock unlock];
  1. NSCondition 是对pthread_cond_init的OC封装
@property (strong, nonatomic) NSCondition *condition;
self.condition = [[NSCondition alloc] init];
    [[[NSThread alloc] initWithTarget:self selector:@selector(__remove) object:nil] start];
    
    [[[NSThread alloc] initWithTarget:self selector:@selector(__add) object:nil] start];
// 线程1
// 删除数组中的元素
- (void)__remove
{
    [self.condition lock];
    NSLog(@"__remove - begin");
    
    if (self.data.count == 0) {
        // 等待
        [self.condition wait];
    }
    
    [self.data removeLastObject];
    NSLog(@"删除了元素");
    
    [self.condition unlock];
}

// 线程2
// 往数组中添加元素
- (void)__add
{
    [self.condition lock];
    
    sleep(1);
    
    [self.data addObject:@"Test"];
    NSLog(@"添加了元素");
    
    // 信号
    [self.condition signal];
    
    sleep(2);
    
    [self.condition unlock];
}
  1. NSRecursiveLock 是对pthread_mutex_tPTHREAD_MUTEX_RECURSIVE的OC封装
@property (strong, nonatomic) NSRecursiveLock *recursiveLock;
self.recursiveLock = [[NSRecursiveLock alloc] init];
- (void)otherTest
{
    [self.recursiveLock lock];
    
    NSLog(@"%s", __func__);
    
    static int count = 0;
    if (count < 10) {
        count++;
        [self otherTest];
    }
    
    [self.recursiveLock unlock];
}
  1. NSConditionLock 锁的顺序控制
@property (strong, nonatomic) NSConditionLock *conditionLock;
self.conditionLock = [[NSConditionLock alloc] initWithCondition:1];
    [[[NSThread alloc] initWithTarget:self selector:@selector(__one) object:nil] start];
    
    [[[NSThread alloc] initWithTarget:self selector:@selector(__two) object:nil] start];
    
    [[[NSThread alloc] initWithTarget:self selector:@selector(__three) object:nil] start];
- (void)__one
{
    [self.conditionLock lock];
    
    NSLog(@"__one");
    sleep(1);
    
    [self.conditionLock unlockWithCondition:2];
}

- (void)__two
{
    [self.conditionLock lockWhenCondition:2];
    
    NSLog(@"__two");
    sleep(1);
    
    [self.conditionLock unlockWithCondition:3];
}

- (void)__three
{
    [self.conditionLock lockWhenCondition:3];
    
    NSLog(@"__three");
    
    [self.conditionLock unlock];
}
  1. dispatch_queue_t GCD也可以控制串行运行,保证数据安全
@property (strong, nonatomic) dispatch_queue_t queue;
self.queue = dispatch_queue_create("ticketQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(self.queue, ^{
    //code
});
  1. dispatch_semaphore_t 控制信号量在1和0之间切换,也可以实现串行运行保证线程安全
@property (strong, nonatomic) dispatch_semaphore_t semaphore;
self.semaphore = dispatch_semaphore_create(1);
    for (int i = 0; i < 20; i++) {
        [[[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil] start];
    }
- (void)test
{
    // 如果信号量的值 > 0,就让信号量的值减1,然后继续往下执行代码
    // 如果信号量的值 <= 0,就会休眠等待,直到信号量的值变成>0,就让信号量的值减1,然后继续往下执行代码
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    NSLog(@"test - %@", [NSThread currentThread]);
    // 让信号量的值+1
    dispatch_semaphore_signal(self.semaphore);
}
  1. @synchronized 不能保证绝对的线程安全
    @synchronized([self class]) { // objc_sync_enter
        [super __saveMoney];
    } // objc_sync_exit

相关文章

  • OC-Lock

    OSSpinLock 自旋锁 (忙等) os_unfair_lock 互斥锁 pthread_mutex_t 跨平...

网友评论

      本文标题:OC-Lock

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