美文网首页
GCD线程锁之信号量

GCD线程锁之信号量

作者: 鐧箪 | 来源:发表于2019-05-29 15:21 被阅读0次
    dispatch_semaphore_t

    信号量通过计数来控制任务的执行
    设置最大的任务量 dispatch_semaphore_create
    发送信号任务量+1 dispatch_semaphore_signal
    移除信号 任务量-1 dispatch_semaphore_wait

    任务量为0的时候会一直等待阻塞所在的线程

    信号量的作用

    • 将异步线程 保持同步执行
    • 线程锁 保证线程的安全

    下面结合GCD的知识 我们来模拟一个场景 做个图片上传模块 一共有10张图片 按批次上传 每批次上传三张 1 2 3 同时异步开始上传 下面的等待 上传完的换下个开始上传 依次类推 因为图片上传的不稳定 可以有的上传快 有的上传慢 模拟基于AFNetWorking 上传的任务都是在异步线程完成 AF用的是operationQueue 我们用GCD模拟

    //设置最大任务量 3
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(3);
        //创建并发队列
        dispatch_queue_t quene = dispatch_queue_create("yc", DISPATCH_QUEUE_CONCURRENT);
        //模拟上传图片的队列
        dispatch_queue_t childQuene = dispatch_queue_create("yb", DISPATCH_QUEUE_CONCURRENT);
        //创建队列组
        dispatch_group_t group = dispatch_group_create();
            NSLog(@"线程0=====%@",[NSThread currentThread]);
            dispatch_group_async(group,quene, ^{
                for (int i = 0; i < 10;  i++) {
                    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
                if (i==3) {
                    dispatch_async(childQuene, ^{
                        NSLog(@"线程2=====%@",[NSThread currentThread]);
                        sleep(20);
                        dispatch_semaphore_signal(semaphore);
                        NSLog(@"%d号图片已上传",3);
                    });
                }else {
                    if (i > 3) {
                        dispatch_group_async(group,childQuene, ^{
                            NSLog(@"线程3=====%@",[NSThread currentThread]);
                        NSLog(@"%d号图片正在上传",i);
                        sleep(2 + i);
                        dispatch_semaphore_signal(semaphore);
                        NSLog(@"%d号图片已上传",i);
                            });
                    }else {
                        NSLog(@"线程1=====%@",[NSThread currentThread]);
                        [NSThread currentThread].name = @"线程1";
                        dispatch_semaphore_signal(semaphore);
                        NSLog(@"%d号图片已上传",i);
                    }
                }
                }
            });
            
            dispatch_group_notify(group, dispatch_get_main_queue(), ^{
                NSLog(@"updateUI");
            });
    
    线程0=====<NSThread: 0x60000275fc00>{number = 1, name = main}
    线程1=====<NSThread: 0x6000027321c0>{number = 3, name = (null)}
    0号图片已上传
    线程1=====<NSThread: 0x6000027321c0>{number = 3, name = 线程1}
    1号图片已上传
    线程1=====<NSThread: 0x6000027321c0>{number = 3, name = 线程1}
    2号图片已上传
    线程2=====<NSThread: 0x600002735780>{number = 4, name = (null)}
    线程3=====<NSThread: 0x600002732240>{number = 5, name = (null)}
    线程3=====<NSThread: 0x600002734bc0>{number = 6, name = (null)}
    5号图片正在上传
    4号图片正在上传
    4号图片已上传
    线程3=====<NSThread: 0x60000272d2c0>{number = 7, name = (null)}
    6号图片正在上传
    5号图片已上传
    线程3=====<NSThread: 0x600002734bc0>{number = 6, name = (null)}
    7号图片正在上传
    6号图片已上传
    线程3=====<NSThread: 0x600002732240>{number = 5, name = (null)}
    8号图片正在上传
    7号图片已上传
    线程3=====<NSThread: 0x6000027321c0>{number = 3, name = 线程1}
    9号图片正在上传
    3号图片已上传
    8号图片已上传
    9号图片已上传
    updateUI
    

    相关文章

      网友评论

          本文标题:GCD线程锁之信号量

          本文链接:https://www.haomeiwen.com/subject/walytctx.html