5. 读写锁
读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理器系统中,它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。
5.1 dispatch_barrier_async / dispatch_barrier_sync
有一个需求,如图:
任务1,2,3 均执行完毕执行任务0,然后执行任务4,5,6.
- (void)lock13 {
dispatch_queue_t queue = dispatch_queue_create("com.qiuxuewei.brrier", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"任务1 -- %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务2 -- %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务3 -- %@",[NSThread currentThread]);
});
dispatch_barrier_sync(queue, ^{
NSLog(@"任务0 -- %@",[NSThread currentThread]);
for (int i = 0; i < 100; i++) {
if (i % 30 == 0) {
NSLog(@"任务0 --- log:%d -- %@",i,[NSThread currentThread]);
}
}
});
NSLog(@"dispatch_barrier_sync down!!!");
dispatch_async(queue, ^{
NSLog(@"任务4 -- %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务5 -- %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务6 -- %@",[NSThread currentThread]);
});
}
复制代码
dispatch_barrier_async 和 dispatch_barrier_sync 的异同
共同点
等待它前面的执行完才执行自己的任务
等待自己任务执行结束才执行后面的任务
不同点
dispatch_barrier_async 将自己的任务插入到队列之后会继续将后面的操作插入到队列,按照规则先执行前面队列的任务,等自己队列执行完毕,再执行后面队列的任务
dispatch_barrier_sync 将自己的任务插入到队列之后,先等待自己的任务执行完毕才会执行后面操作插入到队列,再执行后面队列的任务。
5.2 pthread
- (void)lock14 {
__block pthread_rwlock_t rwlock;
pthread_rwlock_init(&rwlock, NULL);
__block NSMutableArray *arrayM = [NSMutableArray array];
XWBlock writeBlock = ^ (NSString *str) {
NSLog(@"开启写操作");
pthread_rwlock_wrlock(&rwlock);
[arrayM addObject:str];
sleep(2);
pthread_rwlock_unlock(&rwlock);
};
XWVoidBlock readBlock = ^ {
NSLog(@"开启读操作");
pthread_rwlock_rdlock(&rwlock);
sleep(1);
NSLog(@"读取数据:%@",arrayM);
pthread_rwlock_unlock(&rwlock);
};
for (int i = 0; i < 5; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
writeBlock([NSString stringWithFormat"%d",i]);
});
}
for (int i = 0; i < 10; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
readBlock();
});
}
} |