信号量的使用场景


开发中经常会遇到如下两种业务场景:

1 某一个界面需要同时发多个请求,全部请求都成功后再一起刷新界面

2 多个请求必须按照一定顺序执行

3 控制线程开启的数量

这时信号量的作用就显得很牛逼了

信号量常用的三个方法如下所示:

  • dispatch_semaphore_create:创建一个信号量(semaphore
  • dispatch_semaphore_signal:信号通知,即让信号量+1
  • dispatch_semaphore_wait:等待,直到信号量大于0时,即可操作,同时将信号量-1

问题1解决方案:

 dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //请求1
  dispatch_semaphore_t sema = dispatch_semaphore_create(0);
            [网络请求:{
             成功:dispatch_semaphore_signal(sema);
            失败:dispatch_semaphore_signal(sema);
            }];
             dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

 


    });
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //请求2
 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
            [网络请求:{
             成功:dispatch_semaphore_signal(sema);
            失败:dispatch_semaphore_signal(sema);
            }];
             dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //请求3
 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
            [网络请求:{
             成功:dispatch_semaphore_signal(sema);
            失败:dispatch_semaphore_signal(sema);
            }];
             dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ //界面刷新 NSLog(@"任务均完成,刷新界面"); });

问题2解决方案

//第一步:获取token NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ [self task_1]; }]; //第二步:上传七牛 NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ [self task_2]; }]; //第三步:图片地址上传服务器 NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{ [self task_3]; }]; //设置依赖 [operation2 addDependency:operation1]; //任务二依赖任务一 [operation3 addDependency:operation2]; //任务三依赖任务二 //创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO];
- (void)task_1 { //创建信号量并设置计数默认为0 dispatch_semaphore_t sema = dispatch_semaphore_create(0); [self.entityRequest postGetQiNiuTokenSuccess:^(NS_M_RequestOutput *json) { //请求成功 计数+1操作 dispatch_semaphore_signal(sema); } failure:^(NSString *msg) { //请求失败 计数+1操作 dispatch_semaphore_signal(sema); } error:^(NSError *error) { //请求异常 计数+1操作 dispatch_semaphore_signal(sema); }]; //若计数为0则一直等待 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); }
- (void)task_2 { //创建信号量并设置计数默认为0 dispatch_semaphore_t sema = dispatch_semaphore_create(0); [self.entityRequest postGetQiNiuTokenSuccess:^(NS_M_RequestOutput *json) { //请求成功 计数+1操作 dispatch_semaphore_signal(sema); } failure:^(NSString *msg) { //请求失败 计数+1操作 dispatch_semaphore_signal(sema); } error:^(NSError *error) { //请求异常 计数+1操作 dispatch_semaphore_signal(sema); }]; //若计数为0则一直等待 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); }

- (void)task_3 { //创建信号量并设置计数默认为0 dispatch_semaphore_t sema = dispatch_semaphore_create(0); [self.entityRequest postGetQiNiuTokenSuccess:^(NS_M_RequestOutput *json) { //请求成功 计数+1操作 dispatch_semaphore_signal(sema); } failure:^(NSString *msg) { //请求失败 计数+1操作 dispatch_semaphore_signal(sema); } error:^(NSError *error) { //请求异常 计数+1操作 dispatch_semaphore_signal(sema); }]; //若计数为0则一直等待 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); }
问题3解决方案(控制允许同时并发的操作最多只有5次)
dispatch_semaphore_t sema = dispatch_semaphore_create(5);
for (100次循环操作) {
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 操作
        dispatch_semaphore_signal(sema);
    });
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM