GCD 信号量使用记录

需求:

现在有一个页面,有A, B, C 3个网络请求。A, B是非必须,C是必须,所有请求完毕之后要刷新tableView。

这里当然可以使用异步并发,每个请求的成功或者失败中刷新tableView。

如果要用信号量来控制呢?顺便复习一遍吧。

信号量(Semaphore)是多线程环境下的一种保护设施,可以用来保证两个或多个关键代码不被并发调用。

在进入一个关键代码段之前,线程必须获取一个信号量。一旦执行完毕,该线程就会释放信号量。等待下一个信号量被发送,线程才能继续获取到新信号量并再次执行关键代码段。

举个例子:
一个停车场,只能容下5辆车。这时候,来了6辆车。只有前5辆能进去。第6辆车等待,当有一辆车离开停车场时,才能进入。
这里,
想进停车场 —— 创建信号,
当前有车位 ,领卡进场 —— 发信号,
当前无车位,排队等卡 —— 等信号,
离开停车场 —— 销毁信号。
 
dispatch_semaphore_create(long value); //!< 创建信号量
dispatch_semaphore_signal(dispatch_semaphore_t dsema); //!< 发送信号量 +1

dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); //!< 等待信号量 -1


作者:QiShare
链接:https://www.jianshu.com/p/0ae764495c9b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

当信号量为<0时就会阻塞线程,>=0时就继续走。发送信号量 +1 & 等待信号量 -1 是成对出现的

所以 dispatch_semaphore_create(?)函数指定信号量,看情况,一般是指定0

 

测试代码:

-(void)dispatch_group_function1

{

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    

    dispatch_group_t group = dispatch_group_create();

    

    dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{

        

        NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];

        

        NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {

            // 请求完成,可以通知界面刷新界面等操作

            NSLog(@"第一步网络请求完成");

            

            // 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯)

            dispatch_semaphore_signal(semaphore);

        }];

        

        [task resume];

        

        // 以下还要进行一些其他的耗时操作

        NSLog(@"耗时操作继续进行%@",[NSThread currentThread]);

        

        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    });

    

    dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{

        

        NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]];

        

        NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {

            // 请求完成,可以通知界面刷新界面等操作

            NSLog(@"第二步网络请求完成");

            

            // 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯)

            dispatch_semaphore_signal(semaphore);

        }];

        

        [task resume];

        

        // 以下还要进行一些其他的耗时操作

        NSLog(@"耗时操作继续进行%@",[NSThread currentThread]);

        

        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

    });

    

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{

        NSLog(@"刷新界面等在主线程的操作");

    });

}

 

打印信息:


2020-03-25 11:43:16.034584+0800 GCD信号量Demo[14407:221514] 耗时操作继续进行<NSThread: 0x6000011f9a00>{number = 5, name = (null)}


2020-03-25 11:43:16.034584+0800 GCD信号量Demo[14407:221513] 耗时操作继续进行<NSThread: 0x6000011d8400>{number = 6, name = (null)}


2020-03-25 11:43:16.138100+0800 GCD信号量Demo[14407:221516] 第一步网络请求完成


2020-03-25 11:43:22.544131+0800 GCD信号量Demo[14407:221515] 第二步网络请求完成


2020-03-25 11:43:22.544268+0800 GCD信号量Demo[14407:221068] 刷新界面等在主线程的操作

 

 

还有一种方法,设置依赖关系,这里我担心的就是,如果A,B请求出了问题,或者失败了,那C请求还会不会继续呢?

参考https://www.cnblogs.com/tryFighting/p/8178376.html 

NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{

        //block队列1
        [self _fetchBannerImageVoList];
    }];
    NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{

        //block队列2
        [self _fetchRemindData];
    }];
    NSBlockOperation * op3 = [NSBlockOperation blockOperationWithBlock:^{

        //block队列3
        [self _fetchMixArticleVideoData];
    }];
    [op2 addDependency:op1];
    [op3 addDependency:op2];
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];

 

posted @ 2020-03-25 11:37  liuw_flexi  阅读(165)  评论(0编辑  收藏  举报