iOS 读写锁

213 阅读1分钟

iOS提供了2中加读写锁的方式

一.通过pthread_mutex_t实现

1.声明锁
//锁

//初始化读取锁

static pthread_mutex_t r_plock =  PTHREAD_MUTEX_INITIALIZER;

//初始化写入锁

static pthread_mutex_t w_plock =  PTHREAD_MUTEX_INITIALIZER;

//记录当前读取次数,因为只要其值不为0,那么,就说明程序在读取操作,这里停止写入操作
static int current_read_times = 0;
2.初始化锁

//读加锁

- (void)readLock {

    pthread_mutex_lock(&r_plock);

    current_read_times ++;

    if (current_read_times == 1) {

        pthread_mutex_lock(&w_plock);

    }

    pthread_mutex_unlock(&r_plock);

}

  


//读解锁

- (void)readUnLock {

    pthread_mutex_lock(&r_plock);

    current_read_times --;

    if (current_read_times == 0) {

        pthread_mutex_unlock(&w_plock);

    }

    pthread_mutex_unlock(&r_plock);

}

  


//写加锁

- (void)writeLock {

    pthread_mutex_lock(&w_plock);

}

  


//写解锁

- (void)writeUnLock {

    pthread_mutex_unlock(&w_plock);

}

在代码中使用的地方:

写数据

writerLock(写加锁) 需要写的代码 writeUnLock(写解锁)

读数据

readLock(读加锁) 需要读的代码 readUnLock(读解锁)

二.通过栅栏函数实现

下面在贴上一个AFN的实现 , requestHeaderModificationQueue是一个由AFHTTPRequestSerializer创建的并发队列, 使用这个并发队列对一个NSMutableDictionary实现了多读单写的锁

    /// 并发队列
    self.requestHeaderModificationQueue = dispatch_queue_create("requestHeaderModificationQueue", DISPATCH_QUEUE_CONCURRENT);

image.png

读数据

- (id)objectForKey:(NSString *)key {
    __block id obj;
    // 同步读取指定数据:
    dispatch_sync(self.concurrent_queue, ^{
        obj = [self.dataCenterDic objectForKey:key];
    });
    return obj;
}

写数据

- (void)setObject:(id)obj forKey:(NSString *)key {
    // 异步栅栏调用设置数据:
    dispatch_barrier_async(self.concurrent_queue, ^{
        [self.dataCenterDic setObject:obj forKey:key];
    });
}

三 读写锁

读写锁:pthread_rwlock

image.png

// 导入头文件
#import <pthread.h>
 
// 声明属性
@property (nonatomic, assign) pthread_rwlock_t rwlock;
 
 
// 初始化
pthread_rwlock_init(&_rwlock, NULL);
 
// 读加锁
- (void)read {
    pthread_rwlock_rdlock(&_rwlock);
    NSLog(@"read");
    pthread_rwlock_unlock(&_rwlock);
}
 
// 写加锁
- (void)wtite {
    pthread_rwlock_wrlock(&_rwlock);
    NSLog(@"write");
    pthread_rwlock_unlock(&_rwlock);
}
 
// 销毁锁
- (void)dealloc {
    pthread_rwlock_destroy(&_rwlock);
}

总结: 我在项目中使用的是第一种方式,因为项目中写代码是在NSOperationQueue中实现,读代码是在主线程实现,考虑到虽然栅栏函数使用方便,但是是基于GCD队列实现的