首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

iOS 中常见的几种锁-代码示例(5)

iOS 中常见的几种锁-代码示例(5)

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();
            });
        }
    }
返回列表