iOS面试题收纳-多线程之多读单写

78 阅读1分钟

iOS中的多读单写实现方案

pthread_rwlock

// 初始化锁
pthread_rwlock_t lock;
pthread_rwlock_init(&lock, NULL);
// 读 加锁
pthread_rwlock_rdlock(&lock);
// 读 尝试加锁
pthread_rwlock_tryrdlock(&lock);
// 写 加锁
pthread_rwlock_wrlock(&lock);
// 写 尝试加锁
pthread_rwlock_trywrlock(&lock);
// 解锁
pthread_rwlock_unlock(&lock);
// 销毁
pthread_rwlock_destroy(&lock);

dispatch_barrier_async

什么是多读单写?
  1. 多读单写:可以多个读者同时读取数据,在读的时候不能取写入数据。在写的过程中不能有其他写者去写。
  2. 即读者之间是并发的,写者与读者或其他写者是互斥的。
dispatch_barrier_async的用法
  • 这个函数传入的并发队列必须是自己通过dispatch_queue_cretate创建的
  • 如果传入的是一个串行或是一个全局的并发队列,那这个函数便等同于dispatch_async函数的效果
dispatch_queue_t concurrentQueue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);

for (NSInteger i = 0; i < 10; i++) {
    dispatch_async(concurrentQueue, ^{
        NSLog(@"%zd",i);
    });
}

// dispatch_barrier_async上的队列要 和 需要阻塞的任务在同一队列上,否则是无效的。
dispatch_barrier_async(concurrentQueue, ^{
    NSLog(@"barrier");
});

for (NSInteger i = 10; i < 20; i++) {
    dispatch_async(concurrentQueue, ^{
        NSLog(@"%zd",i);
    });
}
  • dispatch_barrier_sync和dispatch_barrier_async的区别就在于会不会阻塞当前线程
完整的多读单写
- (id)readDataForKey:(NSString *)key {
    __block id result;
    dispatch_async(_concurrentQueue, ^{
        result = [self valueForKey:key];
    });
    
    return result;
}

- (void)writeData:(id)data forKey:(NSString *)key {
    dispatch_barrier_async(_concurrentQueue, ^{
        [self setValue:data forKey:key];
    });
}