美文网首页
iOS开发-多线程多任务的依赖的解决方案

iOS开发-多线程多任务的依赖的解决方案

作者: Pandakingli | 来源:发表于2019-07-15 17:33 被阅读0次

    在多线程开发中往往会遇到多个任务并发,但是还有任务之间具有依赖关系,比如下图:


    任务依赖图

    使用NSOperationQueue要比GCD方便一些,代码更简洁。

    1. 使用NSOperationQueue设置依赖

    - (void)testOperation {
        NSLog(@"开始----%@",[NSThread currentThread]);
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        NSBlockOperation *opA = [NSBlockOperation blockOperationWithBlock:^{
            
            sleep(3);
            NSLog(@"完成任务A----%@",[NSThread currentThread]);
        }];
        
        NSBlockOperation *opB = [NSBlockOperation blockOperationWithBlock:^{
            
            sleep(2);
            NSLog(@"完成任务B---%@",[NSThread currentThread]);
        }];
        
        NSBlockOperation *opC = [NSBlockOperation blockOperationWithBlock:^{
           
            sleep(1);
             NSLog(@"完成任务C---%@",[NSThread currentThread]);
        }];
        
        NSBlockOperation *opD = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"完成任务D---%@",[NSThread currentThread]);
        }];
        
        NSBlockOperation *opE = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"完成任务E---%@",[NSThread currentThread]);
        }];
        
        [opD addDependency:opA];
        [opD addDependency:opB];
        
        [opE addDependency:opB];
        [opE addDependency:opC];
        
        
        [queue addOperation:opA];
        [queue addOperation:opB];
        [queue addOperation:opC];
        [queue addOperation:opD];
        [queue addOperation:opE];
    }
    
    

    运行结果:

    2019-07-15 17:07:57.918930+0800 xxtest[62847:2808690] 开始----<NSThread: 0x600002dbe900>{number = 1, name = main}
    2019-07-15 17:07:58.922080+0800 xxtest[62847:2808777] 完成任务C----<NSThread: 0x600002dc3780>{number = 3, name = (null)}
    2019-07-15 17:07:59.924180+0800 xxtest[62847:2808780] 完成任务B----<NSThread: 0x600002dc37c0>{number = 4, name = (null)}
    2019-07-15 17:07:59.924480+0800 xxtest[62847:2808792] 完成任务E----<NSThread: 0x600002dc59c0>{number = 5, name = (null)}
    2019-07-15 17:08:00.921409+0800 xxtest[62847:2808779] 完成任务A----<NSThread: 0x600002dc5900>{number = 6, name = (null)}
    2019-07-15 17:08:00.921659+0800 xxtest[62847:2808778] 完成任务D----<NSThread: 0x600002d35500>{number = 7, name = (null)}
    
    

    2. 使用 @synchronized+dispatch_semaphore

    //@property(nonatomic,strong) NSObject *mySyn;
    //@property(nonatomic,strong) NSLock *lockD;
    //@property(nonatomic,strong) NSLock *lockE;
    
    -(void)synTest{
        
         NSLog(@"开始----%@",[NSThread currentThread]);
        dispatch_queue_t queue =  dispatch_queue_create("com.xxx.customQueue", DISPATCH_QUEUE_CONCURRENT);
        self.mySyn = [[NSObject alloc]init];
        self.D_count = 0;
        self.E_count = 0;
        
        dispatch_semaphore_t D_sema = dispatch_semaphore_create(0);
        dispatch_semaphore_t E_sema = dispatch_semaphore_create(0);
        
        dispatch_async(queue, ^{
            
            sleep(3);
            NSLog(@"完成任务A----%@",[NSThread currentThread]);
            @synchronized (self.mySyn) {
                self.D_count = self.D_count + 1;
                if (self.D_count==2) {
                    dispatch_semaphore_signal(D_sema);
                }
            }
            
        });
        
        dispatch_async(queue, ^{
            
            sleep(2);
             NSLog(@"完成任务B----%@",[NSThread currentThread]);
            
            @synchronized (self.mySyn) {
                self.D_count = self.D_count + 1;
                if (self.D_count==2) {
                    dispatch_semaphore_signal(D_sema);
                }
                
                self.E_count = self.E_count + 1;
                if (self.E_count==2) {
                    dispatch_semaphore_signal(E_sema);
                }
            }
           
            
        });
        
        dispatch_async(queue, ^{
            
            sleep(1);
             NSLog(@"完成任务C----%@",[NSThread currentThread]);
            
            @synchronized (self.mySyn) {
                self.E_count = self.E_count + 1;
                if (self.E_count==2) {
                    dispatch_semaphore_signal(E_sema);
                }
            }
            
            
        });
        
        dispatch_async(queue, ^{
            dispatch_semaphore_wait(D_sema, DISPATCH_TIME_FOREVER);
             NSLog(@"完成任务D----%@",[NSThread currentThread]);
            dispatch_semaphore_signal(D_sema);
        });
        
        dispatch_async(queue, ^{
            dispatch_semaphore_wait(E_sema, DISPATCH_TIME_FOREVER);
             NSLog(@"完成任务E----%@",[NSThread currentThread]);
            dispatch_semaphore_signal(E_sema);
            
        });
        
      
        
    }
    
    

    执行结果:

    2019-07-15 17:11:18.540308+0800 xxtest[62873:2811422] 开始----<NSThread: 0x60000118f600>{number = 1, name = main}
    2019-07-15 17:11:19.544241+0800 xxtest[62873:2811459] 完成任务C----<NSThread: 0x6000011081c0>{number = 3, name = (null)}
    2019-07-15 17:11:20.544484+0800 xxtest[62873:2811456] 完成任务B----<NSThread: 0x6000011dc180>{number = 4, name = (null)}
    2019-07-15 17:11:20.544678+0800 xxtest[62873:2811529] 完成任务E----<NSThread: 0x6000011f4d80>{number = 5, name = (null)}
    2019-07-15 17:11:21.545102+0800 xxtest[62873:2811457] 完成任务A----<NSThread: 0x60000110b040>{number = 6, name = (null)}
    2019-07-15 17:11:21.545316+0800 xxtest[62873:2811458] 完成任务D----<NSThread: 0x6000011fb180>{number = 7, name = (null)}
    
    

    3. 使用 dispatch_group+dispatch_semaphore

    
    -(void)groupAndSema{
        
        NSLog(@"开始----%@",[NSThread currentThread]);
        
        dispatch_queue_t queue =  dispatch_queue_create("com.xxx.customQueue", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_semaphore_t B_sema = dispatch_semaphore_create(0);
        
        dispatch_group_t groupAB =dispatch_group_create();
        
        dispatch_group_async(groupAB,queue, ^{
            sleep(3);
            NSLog(@"完成任务A----%@",[NSThread currentThread]);
        });
        
        dispatch_group_async(groupAB,queue, ^{
            sleep(2);
            NSLog(@"完成任务B----%@",[NSThread currentThread]);
              dispatch_semaphore_signal(B_sema);
        });
        
        dispatch_group_t groupBC =dispatch_group_create();
        dispatch_group_async(groupBC,queue, ^{
            dispatch_semaphore_wait(B_sema, DISPATCH_TIME_FOREVER);
        });
        
        dispatch_group_async(groupBC,queue, ^{
            sleep(1);
            NSLog(@"完成任务C----%@",[NSThread currentThread]);
        });
        
        
        dispatch_group_notify(groupAB,queue, ^{
           NSLog(@"完成任务D----%@",[NSThread currentThread]);
        });
        
        dispatch_group_notify(groupBC,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
            NSLog(@"完成任务E----%@",[NSThread currentThread]);
        });
    }
    
    
    2019-07-16 11:07:23.328392+0800 xxtest[5590:141062] 开始----<NSThread: 0x600000fba880>{number = 1, name = main}
    2019-07-16 11:07:24.328872+0800 xxtest[5590:141167] 完成任务C----<NSThread: 0x600000f3c680>{number = 3, name = (null)}
    2019-07-16 11:07:25.329991+0800 xxtest[5590:141154] 完成任务B----<NSThread: 0x600000fdd240>{number = 4, name = (null)}
    2019-07-16 11:07:25.330212+0800 xxtest[5590:141166] 完成任务E----<NSThread: 0x600000f3c6c0>{number = 5, name = (null)}
    2019-07-16 11:07:26.328750+0800 xxtest[5590:141156] 完成任务A----<NSThread: 0x600000fcad40>{number = 6, name = (null)}
    2019-07-16 11:07:26.328931+0800 xxtest[5590:141156] 完成任务D----<NSThread: 0x600000fcad40>{number = 6, name = (null)}
    
    

    相关文章

      网友评论

          本文标题:iOS开发-多线程多任务的依赖的解决方案

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