[网络和多线程]6、GCD 队列和任务

本文深入探讨了GCD(Grand Central Dispatch)在多核并行计算中的应用,包括其优势、基本概念、队列类型及任务执行方式,并通过实例演示了不同场景下任务的具体执行流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

6、GCD 队列和任务
          【网络多线程】
--------------------------------------------------------------------------------------------------------------


GCD的基本概念

  • 什么是GCD
GCD英文全称 Grand Center Dispatch ——— 牛逼的中枢调度器,他是纯C的。

  • GCD的优势
GCD是苹果公司为多核心的并行运算提出的解决方案
GCD会自动利用更多的CPU内核(比如双核、四核)
GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
程序员只需要告诉GCD要执行什么任务,不需要编写任何线程管理代码
  • GCD的使用2个步骤
定制任务 ——— 确定想做的事情
将任务添加到队列 ——— GCD会按照FIFI原则,自动将队列的任务取出,放到对应的
    任务中去执行。

GCD在库 libdispatch,这个库会在运行中动态加载,不需要我们手动添加,他的API是
 纯C的函数,基本都是以dispatch开始。


任务的执行方式:同步、异步

同步方式执行任务
同步就是任务按照顺序来做,他用下面的方法来做

    /**

     *  同步执行任务

     *

     *  @param queue 任务要添加到那个队列

     *  @param block 要执行的任务

     */

    void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);


       用异步的方式执行任务

    /**

     *  异步执行任务

     *

     *  @param queue 任务要添加到那个队列

     *  @param block 要执行的任务

     */

    void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);


同步和异步的执行

同步:在当前线程中执行

异步:在另一条线程中执行


队列的类型:串行队列、并发队列


并发队列 Concurrent Dispatch Queue

可以让多个任务并发执行(自动开启多个线程同时执行任务),并发队列只有在

异步函数(dispatch_async)下才有效。


串行队列 Serial dispatch Queue

让任务一个接一个的执行(一个任务执行完毕后再执行下一个队列)

同步和异步决定要不要开新的线程

同步  :  在当前线程中执行任务,不具备开线程的能力

异步 : 在新的线程中执行任务,具备开启线程的能力

并发和穿行决定了任务的执行方式

并发 : 多个任务并发执行

串行 : 一个任务执行完毕后再执行下一个任务



获取队列的方法


并发队列

GCD默认提供了全局的并发队列,供整个应用使用,不需要手动创建使用,获得并发

队列的函数:

/**

 *  获取全局队列(并发队列)

 *

 *  @param identifier 队列的优先级

 *  @param flags      保留使用,默认0

 *

 *  @return 获取的全局队列

 */

dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);



获取串行队列有两种途径

/**

 *  创建串行队列

 *

 *  @param label 队列的名称

 *  @param attr  队列的属性,一般nil

 *

 *  @return 创建的队列

 */

dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);




任务执行的四种方式分析


第一种 : 同步任务下使用串行队列

/**

 *  同步任务 ------ 串行队列

 */

- (void)syncFuncSerialQueue {

    // 创建队列

    dispatch_queue_t tSerialQueue = dispatch_queue_create("serial queue synsc"NULL);

    

    // 创建任务

    dispatch_sync(tSerialQueue, ^{

        NSLog(@"%@ tSerialQueue -- sync task1",[NSThread currentThread]);

    });


    dispatch_sync(tSerialQueue, ^{

        NSLog(@"%@ tSerialQueue -- sync task2",[NSThread currentThread]);

    });

    

    dispatch_sync(tSerialQueue, ^{

        NSLog(@"%@ tSerialQueue -- sync task3",[NSThread currentThread]);

    });

    // 结论  没有开新的线程,三个任务都在主线程执行

}


结果输出:没有开启新的线程,三个任务都在主线程下执行。


第二种 : 同步任务下使用并行队列

/**

 *  同步任务 ------ 并行队列

 */

- (void)syncFuncMainQueue {

    // 获取主队列

    dispatch_queue_t tMainQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    

    // 创建同步任务

    dispatch_sync(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- sync task1",[NSThread currentThread]);

    });

    

    dispatch_sync(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- sync task2",[NSThread currentThread]);

    });

    

    dispatch_sync(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- sync task3",[NSThread currentThread]);

    });

    // 结论  没有开新的线程,三个任务都在主线程执行

}

结果输出:没有开启新的线程,三个任务都在主线程下执行。


/**

 *  同步任务 ------ 串行队列

 */

- (void)syncFuncSerialQueue {

    // 创建队列

    dispatch_queue_t tSerialQueue = dispatch_queue_create("serial queue synsc"NULL);

    

    // 创建任务

    dispatch_sync(tSerialQueue, ^{

        NSLog(@"%@ tSerialQueue -- sync task1",[NSThread currentThread]);

    });


    dispatch_sync(tSerialQueue, ^{

        NSLog(@"%@ tSerialQueue -- sync task2",[NSThread currentThread]);

    });

    

    dispatch_sync(tSerialQueue, ^{

        NSLog(@"%@ tSerialQueue -- sync task3",[NSThread currentThread]);

    });

    // 结论  开启一条新的线程,但是三个任务都在一条线程执行

}


结果输出:开启一条新的线程,三个任务都在一条线程执行



第四种 : 异步任务下使用异步队列(1,1)

/**

 *  异步任务 ------ 并行队列

 */

- (void)syncFunctMainQueue {

    // 获取主队列

    dispatch_queue_t tMainQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    

    // 创建异步任务

    dispatch_async(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- async task1",[NSThread currentThread]);

    });

    

    dispatch_async(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- async task2",[NSThread currentThread]);

    });

    

    dispatch_async(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- async task3",[NSThread currentThread]);

    });

    // 结论  开启多条线程,三个任务都在不同的非主线程中执行

}


结果输出:


结论:

同步(sync)函数

  • 并发队列 : 不会开线程
  • 串行队列  :  不会开线程


异步(async)函数

  • 并发队列 : 能开多条线程
  • 串行队列  :  开启1条线程


注意

凡是函数名带有 creat/copy/new/retaion等字眼,都需要用release手动释放,GCD的数据类型在ARC的环境下不需要再做release,所以当遇见这些字 

眼,先试着手动release。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值