GCD 使用总结

125 阅读3分钟

gcd:

1.不需要自己管理线程生命周期.

2.GCD 可用于多核的并行运算;

3.GCD 会自动利用更多的 CPU 内核(比如双核、四核);

4.GCD 会自动管理线程的生命周期(创建线程、调度任务、销毁线程)

5.程序员只需要告诉 GCD 想要执行什么任务,不需要编写任何线程管理代码。

队列和任务

任务: 就是我们要执行的代码块. 任务的执行分为同步执行 就是下一个任务要等待上一个任务完成后才能执行 和异步执行 所有任务无序执行.其中异步执行有开启新线程的能力.但不一定开启.

队列 就是任务执行的位置.用来存放待执行的任务.队列采用FIFO即先进先出原则.队列的执行分为:

  **串行队列**:串行队列是指队列顺序执行
  **并发队列**:可以让多个任务并发(同时)执行。(可以开启多个线程,并且同时执行任务)

dispatch_queue_t 与 dispatch_group_t 含义

  ## dispatch_queue_t 队列 包含多个任务,通过参数决定是异步执行还是同步执行.
  ## dispatch_group_t 队列组 是包含多个队列,通过参数决定串行还是并行.并指定队列的执行优先级,一般使用默认就好.

注意 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 这是系统为我们创建的全局并发队列

下面写一些例子来实际了解一下GCD的使用

1.异步操作同步执行 ,信号量的应用

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
   __block NSInteger number = 0;
   for (int i = 0; i<10; i++) {

       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

           number += 1;
           dispatch_semaphore_signal(semaphore);
       });

       dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

       NSLog(@"semaphore---end,number = %zd",number);

   }

2.实现上述功能,串行队列 + 异步也阔以实现

//:创建串行队列
dispatch_queue_t queue = dispatch_queue_create(@"queue1", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        NSLog(@"任务1%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"任务2%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"任务3%@",[NSThread currentThread]);
    });
输出为:1,2,3 同一线程

3.等待多个网络请求全部返回,去刷新UI

    //:形式1.创建dispatch_group_t 队列
   dispatch_group_t group = dispatch_group_create();
   //:执行第一个下载任务
   dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
       NSLog(@"任务1%@",[NSThread currentThread]);
   });
   //:执行第二个下载任务
   dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
       NSLog(@"任务2%@",[NSThread currentThread]);
   });
   //:执行第三个下载任务
   dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
       NSLog(@"任务3%@",[NSThread currentThread]);
   });
   dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
       NSLog(@"所有任务完成");
   });
   //:形式2.创建dispatch_group_t 队列
dispatch_group_t group = dispatch_group_create();
   
   dispatch_group_enter(group);
   NSLog(@"任务%@",[NSThread currentThread]);
   dispatch_group_leave(group);
   dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
       NSLog(@"所有任务完成");
   });

4.使用栅栏函数实现,多读单写.待补充. 需求 四个请求 其中任务0 需要在1,2执行完成之后才能执行0 然后才能执行3,4,5,

dispatch_barrier_async 使用不等待 本身block 代码执行完成就执行下面 主线程的任务 注意是主线程
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
   dispatch_async(queue, ^{
       NSLog(@"-------1----%@",[NSThread currentThread]);
   });
   dispatch_async(queue, ^{
       NSLog(@"-------2----%@",[NSThread currentThread]);
   });
   dispatch_barrier_async(queue, ^{//不能使用全局队列
       NSLog(@"barrier");
   });
   dispatch_async(queue, ^{
       NSLog(@"------3----%@",[NSThread currentThread]);
   });
   dispatch_async(queue, ^{
       NSLog(@"-------4----%@",[NSThread currentThread]);
   });

   NSLog(@"-------5----%@",[NSThread currentThread]);

输出:5,1,2,3,4
 dispatch_barrier_sync 使用要等待 本身block 代码执行完成才执行下面 主线程或子线程任务 
   dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
   dispatch_async(queue, ^{
       NSLog(@"-------1----%@",[NSThread currentThread]);
   });
   dispatch_async(queue, ^{
       NSLog(@"-------2----%@",[NSThread currentThread]);
   });
   dispatch_barrier_sync(queue, ^{//不能使用全局队列
       NSLog(@"barrier");
   });
   dispatch_async(queue, ^{
       NSLog(@"------3----%@",[NSThread currentThread]);
   });
   dispatch_async(queue, ^{
       NSLog(@"-------4----%@",[NSThread currentThread]);
   });

   NSLog(@"-------5----%@",[NSThread currentThread]);
输出:,1,2,5,3,4