ios多线程--GCD

GCD全称Grand Central Dispatch,纯C语言,提供了很多强大的函数,现在ios开发中非常主流的多线程开发方式,记录一下基本原理以及面试中

GCD的两个核心概念:
任务:执行的操作 队列:用于存放任务
将任务添加到队列中,GCD会自动将任务取出,放到对应的线程中去执行,取出遵循队列的FIFO:先进先出


执行任务分为同步和异步: 主要影响能不能开启新的线程,针对的是线程
dispatch_sync 同步方式:只能在当前线程执行任务,不具备开启新线程的能力
dispatch_async 异步方式:可以在新的线程执行任务,具备开启新线程的能力

队列的类型分为串行和并行: 主要影响任务的执行方式,针对的是队列
DISPATCH_QUEUE_SERIAL 串行队列:任务按顺序的执行,一个任务执行完毕后再执行下一个任务
DISPATCH_QUEUE_CONCURRENT 并发队列:可以多个任务同时执行,自动开启多个线程执行任务,此队列只有在异步函数下才有效

//同步串行
    dispatch_queue_t queue = dispatch_queue_create("com.gcd", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
        NSLog(@"任务");
    });
//异步串行
    dispatch_queue_t queue = dispatch_queue_create("com.gcd", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        NSLog(@"任务");
    });
//同步并发
    dispatch_queue_t queue = dispatch_queue_create("com.gcd", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(queue, ^{
        NSLog(@"任务");
    });
//异步并发
    dispatch_queue_t queue = dispatch_queue_create("com.gcd", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"任务");
    });

这里有一个死锁的概念:使用sync函数往当前的串行队列中添加任务,会卡住当前的串行队列,造成死锁
死锁的两个必要条件:串行队列,同步任务


GCD的其他用法:
定时器:
NSTimer延时误差要大, NSTimer是在RunLoop中, RunLoop要处理各种东西(source,timer,observe),有时导致NSTimer不是特别准
GCD的定时器不受RunLoop中Mode的影响, 比如滚动TableView的时候,GCD的定时器不受影响,因为RunLoop内部也是基于GCD实现的

    timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"1");
    });
    dispatch_resume(timer);

    其中dispatch_source_t timer;需要设置全局变量

延时操作:
GCD不可以取消延时

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"1");
    });

    其他的实现方式:
    perfromselect  runloop要手动开启 主线程的runloop是默认开启的,而子线程需手动开启
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self performSelector:@selector(afterEvent:) withObject:self afterDelay:2];
        NSLog(@"begin");
        [[NSRunLoop currentRunLoop] run];
    });

队列组:
可以让多个异步请求按照顺序去执行,当一个任务完成之后,一定要离开组,进入组和离开组必须成对出现

    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t t = dispatch_get_global_queue(0, 0);

    dispatch_group_enter(group);//进入组
    dispatch_async(queue, ^{
        //进行锁定的异步线程任务
        dispatch_group_leave(group);//离开组
    });

栅栏函数:
访问数据库或者文件的时候,读写锁,作用,可以更高效的访问数据库和文件,有效的避免数据竞争

    dispatch_queue_t t = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(t, ^{

        NSLog(@"1");
    });
    dispatch_async(t, ^{
        NSLog(@"2");
    });
    dispatch_barrier_async(t, ^{
        NSLog(@"barrier");
    });
    dispatch_async(t, ^{
        sleep(2);
        NSLog(@"3");
    });
    dispatch_async(t, ^{

        NSLog(@"4");
    });
    sleep(2);
    NSLog(@"end");
    输出的结果能够保证barrier在1234中间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值