GCD

作者: e521 | 来源:发表于2023-01-30 14:49 被阅读0次
    1、什么是gcd?
    • 全称是Grand Central Dispatch;
    • 纯C语言,提供了很多强大的函数;
    • 是苹果公司为多核的并行运算提供的解决方案,会自动的利用更多的cpu内核,能自动管理线程的生命周期。

    2、线程和队列的关系?

    • 队列是任务的管理者,线程是任务的执行者。

    3、队列有几种?

    • 队列分为串行队列(FIFO)和并发队列,主队列属于串行队列,全局队列属于并发队列。主队列在main函数之前就已经创建了。

    4、iOS多线程的方案有哪些?

    • iOS多线程方案分为四种:pthread,NSThread,GCD和NSOpreation。
    • 其中pthread,NSThread,需要开发者手动管理线程的生命周期。
    • NSOpreation是对GCD面向对象的封装,NSOpreation提供了添加线程的依赖关系,设置线程优先级,观察线程状态,暂停,继续,取消线程等方法,方便开发者使用,但效率方面不如GCD。

    5、举例说明线程的死锁问题

        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
        dispatch_async(queue, ^{
            NSLog(@"1");
            dispatch_sync(queue, ^{
                NSLog(@"2");
            });
            NSLog(@"3");
        });
    
    • 解析:DISPATCH_QUEUE_SERIAL说明是串行队列,遵循FIFO原则, dispatch_async异步函数中有3个任务NSLog(@"1"),dispatch_sync(queue, ^{}),NSLog(@"3")会首先加入到串行队列queue中,且依次执行,但在执行dispatch_sync(queue, ^{})时,因为这里是一个同步函数,要想代码块执行完毕,此时就必须执行NSLog(@"2"),但NSLog(@"2")也是加入到同一个队列queue中的,且其排在NSLog(@"3")打印之后,所以此时就会出现互相等待的现象,想要执行NSLog(@"3")就必须执行完毕dispatch_sync(queue, ^{})代码块,想要执行完代码块就必须执行完NSLog(@"2"),想要执行完NSLog(@"2")就必须执行完NSLog(@"3")
    死锁逻辑

    6、常用的GCD方法及使用环境

    • 同步函数(不具备开启新线程的能力)
    dispatch_sync(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    
    • 异步函数(并发队列中具备开启新线程的能力)
    dispatch_async(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    
    • 信号量dispatch_semaphore_t
    • 当信号量为0的时候会堵塞线程,起到一种锁的效果
    //  创建信号量 value可控制并发数量
    dispatch_semaphore_create(<#intptr_t value#>)
    // 信号量-1
    dispatch_semaphore_wait(<#dispatch_semaphore_t  _Nonnull dsema#>, <#dispatch_time_t timeout#>)
    // 信号量 +1
    dispatch_semaphore_signal(<#dispatch_semaphore_t  _Nonnull dsema#>)
    
    • 栅栏函数dispatch_barrier_async
    • 将函数两边的任务隔开,栅栏函数之前的任务执行完毕之后,才会执行栅栏函数之后的任务
    dispatch_barrier_async(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    
    • 线程组函数dispatch_group_t
    // 创建线程组 
    dispatch_group_create()
    // 线程组异步执行
    dispatch_group_async(<#dispatch_group_t  _Nonnull group#>, <#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    // 线程组所有函数执行完毕之后将会调用该函数
    dispatch_group_notify(<#dispatch_group_t  _Nonnull group#>, <#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    //进组和出组函数 成对出现 可使用这俩函数建立任务之间的依赖关系
    dispatch_group_enter(<#dispatch_group_t  _Nonnull group#>)
    dispatch_group_leave(<#dispatch_group_t  _Nonnull group#>)
    
    • 延时函数dispatch_after
    • 可以用该函数做一些延时任务
    dispatch_after(<#dispatch_time_t when#>, <#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    
    • 一次执行函数dispatch_once
    • 代码块内的操作只会执行一次,常在创建单利的时候使用
    dispatch_once(<#dispatch_once_t * _Nonnull predicate#>, <#^(void)block#>)
    
    • source函数 dispatch_source_t
    • 常用于实现定时器的功能,精准度高于NSTimer(具体实现可参考 dispatch_source_t详解
    // 创建
    dispatch_source_create(<#dispatch_source_type_t  _Nonnull type#>, <#uintptr_t handle#>, <#uintptr_t mask#>, <#dispatch_queue_t  _Nullable queue#>)
    // 回调函数
    dispatch_source_set_event_handler(<#dispatch_source_t  _Nonnull source#>, <#^(void)handler#>)
    

    相关文章

      网友评论

          本文标题:GCD

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