信號量的使用場景


開發中經常會遇到如下兩種業務場景:

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