- 同一时间,只能有1个线程进行写的操作
- 同一时间,允许有多个线程进行读的操作
- 同一时间,不允许既有写的操作,又有读的操作
上面这样的场景就是典型的“多读单写”,经常用于文件等数据的读写操作,iOS中的实现方案有:
-
pthread_rwlock
读写锁 (内部已经实现了) -
dispatch_barrier_async
异步栅栏调用
1、pthread_rwlock
读写锁
- 读写锁方法列表
// 初始化锁
pthread_rwlock_t lock;
pthread_rwlock_init(&lock, NULL);
// 读-加锁
pthread_rwlock_rdlook(&lock);
// 读-尝试加锁
pthread_rwlock_tryrdlock(&lock);
// 写-加锁
pthread_rwlock_wrlock(&lock);
// 写-尝试加锁
pthread_rwlock_trywrlock(&lock);
// 解锁
pthread_rwlock_unlock(&lock);
// 锁毁
pthread_rwlock_destroy(&lock);
- 初始化一把锁:
@property(assgin, nonatomic) pthread-rwlock_t lock;
// init
pthread_rwlock_init(&lock, NULL);
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
for (int i=0;i<10;i++) {
dispatch_async(queue, ^{
[self read];
});
dispatch_async(queue, ^{
[self write];
});
}
例:
-(void)read
{
pthread_rwlock_rdlock(&_lock);
// 读操作
pthread_rwlock_unlock(&_lock);
}
-(void)write
{
pthread_rwlock_wrlock(&_lock);
// 写操作
pthread_rwlock_unlock(&_lock);
}
2、dispatch_barrier_async
- 这个函数传入的并发队列必须是自己通过
dispatch_queue-create
创建的,全局并发队列或串行队列是没有效果的 - 如果传入的是一个串行队列或是一个全局的并发队列,那这个函数便等同于
dispatch_async
函数的效果
// 初始化队列
dispatch_queue_t queue = dispatch_queue_create("rw_queue", DISPATCH_QUEUE_CONCURRENT);
// 读
dispatch_async(queue, ^{
});
// 写
dispatch_barrier_async(queue, ^{
});
// 建立了一个栅栏的东西, 起一个栅栏,在写的前后树立一个屏障,把写的任务执行完,才可以继续其它操作
例:读可以同时读,写不一样了,因为建立了屏障,只能等一个写操作执行完,才会继续其它的读操作和下一次写操作。
{
self.queue = dispatch_queue-createa("rw_queue", DISPATCH_QUEUE_CONCURRENT);
}
-(void)read
{
dispatch_async(self. queue, &{
// 读
});
}
-(void)write
{
dispatch_barrier_async(queue, ^{
// 写
});
}