栅栏函数、线程组、信号量笔记

1,120 阅读2分钟

栅栏函数

    /*
     1.异步栅栏函数阻塞的是队列,而且必须是自定义的并发队列,不影响主线程任务的执行
     2.同步栅栏函数阻塞的是线程,且是主线程,会影响主线程其他任务的执行
     */
    
    /**
     1.同步栅栏函数dispatch_barrier_sync(在主线程中执行):前面的任务执行完毕才会来到这里,但是同步栅栏函数会堵塞线程,影响后面的任务执行
     2.异步栅栏函数dispatch_barrier_async:前面的任务执行完毕才会来到这里
     3.在使用栅栏函数时使用自定义队列才有意义,如果用的是串行队列或者系统提供的全局并发队列,这个栅栏函数的作用等同于一个同步函数的作用,没有任何意义
     */
    
    dispatch_queue_t concurrentQueue = dispatch_queue_create("objective", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(concurrentQueue, ^{
        NSLog(@"1");
    });
    
    dispatch_async(concurrentQueue, ^{
        NSLog(@"3");
    });
    
    dispatch_barrier_async(concurrentQueue, ^{
        NSLog(@"栅栏函数任务~");
    });
    NSLog(@"4");

    //改成同步 1、3、栅栏函数任务、4

信号量

    /**
     1.dispatch_semaphore_create 主要就是初始化信号量
     2.dispatch_semaphore_wait是对信号量的value进行--,即加锁操作
     3.dispatch_semaphore_signal 是对信号量的value进行++,即解锁操作
     */
   
    dispatch_semaphore_t sem = dispatch_semaphore_create(1);
    dispatch_queue_t queue = dispatch_queue_create("测试", DISPATCH_QUEUE_CONCURRENT);
    ///举例一 同步作用
    for (NSInteger i = 0; i < 10; i ++) {
        dispatch_async(queue, ^{
            dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
            NSLog(@"%@", [NSString stringWithFormat:@"任务%ld",i]);//按顺序执行
            dispatch_semaphore_signal(sem);
        });
    }
    ///举例二 多线程安全
   __block NSInteger value = 10;
    for (NSInteger i = 0; i < 10; i ++) {
        dispatch_async(queue, ^{
            dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
            value --;
            NSLog(@"%ld", (long)value);
            dispatch_semaphore_signal(sem);
        });
    }

线程组

    /**相关函数-用来控制多个异步任务结束 回到同一地方
     dispatch_group_create
     dispatch_group_async 任务
     dispatch_group_notify 任务执行完毕通知
     dispatch_group_wait 进组任务执行等待时间
     //进组和出组成对使用的
     dispatch_group_enter 进组
     dispatch_group_leave 出组
     */
    
    ///1.异步函数搭配enter leave
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"111111");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"22222");
        dispatch_group_leave(group);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"所有异步结束后 回到这里");
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        sleep(2);
        NSLog(@"33333");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"44444");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        sleep(5);
        NSLog(@"666666");
        dispatch_group_leave(group);
    });
    
    ///2.dispatch_group_async 使用
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("22", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"11111111");
    });

    dispatch_group_async(group, queue, ^{
        sleep(6);
        NSLog(@"2222222");
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"3333333");
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"666666");
    });
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"更新————————");///始终等异步全部执行完回到这里
    });