ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GCD(2/2) 信号量和栅栏

2021-01-16 12:33:20  阅读:267  来源: 互联网

标签:queue 栅栏 GCD dispatch 信号量 任务 semaphore name


一、信号量

信号量是控制资源访问数量的标识
当信号量大于 0 时,可以访问资源;当信号量等于 0 时无法访问资源

// 创建一个 semaphore
dispatch_semaphore_create 
// 发送一个信号  
dispatch_semaphore_signal
// 等待可用信号访问资源    
dispatch_semaphore_wait     

1、控制资源访问并发数

    dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
    dispatch_semaphore_t dsema = dispatch_semaphore_create(4);
    
    for (NSInteger i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER);
            sleep(3);
            NSLog(@"%ld", i);
            dispatch_semaphore_signal(dsema);
        });
    }

2、将异步执行任务切换为同步执行任务

    dispatch_semaphore_t dsema = dispatch_semaphore_create(0);
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    dispatch_async(queue, ^{
        NSLog(@"耗时任务开始");
        sleep(3);
        NSLog(@"耗时任务结束");
        dispatch_semaphore_signal(dsema);
    });

    dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER);
    NSLog(@"刷新 UI");

二、栅栏

栅栏任务会对任务队列进行分割实现如下效果:
栅栏任务之前的任务执行完成之后开始执行栅栏任务。
栅栏任务之后的任务在栅栏任务执行完成之后开始执行
1、栅栏只对自定义队列即 dispatch_queue_create 创建的队列有效。
2、两个重要函数
异步地添加任务

dispatch_barrier_async(queue, ^{

});

同步地添加执行

dispatch_barrier_sync(queue, ^{

});

3、栅栏作用的效果测试

    for (NSInteger i = 1; i <= 20; i++) {
        if (i == 6) {
            dispatch_barrier_async(queue, ^{
                sleep((arc4random() % 100 + 50) / 100.0);
                NSLog(@"%ld", i);
            });
        } else if (i == 11) {
         dispatch_barrier_async(queue, ^{
             sleep((arc4random() % 100 + 50) / 100.0);
             NSLog(@"%ld", i);
         });
        } else {
         dispatch_async(queue, ^{
             sleep((arc4random() % 100 + 50) / 100.0);
             NSLog(@"%ld", i);
         });
        }
    }


4、多线程、安全地对数据进行读写操作
在并行队列中,异步地添加读取任务,异步(同步也可以)地添加栅栏写入任务。
效果:每次写入任务之前的读取任务必须执行完成之后才会执行本次写入任务;

_queue = dispatch_queue_create("custom", DISPATCH_QUEUE_CONCURRENT);

- (NSString *)name {
    __block NSString *name;
    dispatch_async(_queue, ^{
        name = self->_name;
    });
    return name;
}

- (void)setName:(NSString *)name {
    dispatch_barrier_async(_queue, ^{
        self->_name = name;
    });
}

标签:queue,栅栏,GCD,dispatch,信号量,任务,semaphore,name
来源: https://www.cnblogs.com/ebamboo/p/14285486.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有