码迷,mamicode.com
首页 > 移动开发 > 详细

iOS GCD 的理解 (一)

时间:2016-08-04 19:16:15      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:

  • 基本概念

  了解多线程之前,首先我们要对操作系统关于多线程方面的名词解释一下,学过操作系统课程的同学可以跳过。

  1. 进程: 一个具有一定独立功能的程序关于某个数据集合的一次运行活动。可以理解成一个运行中的APP。
  2. 线程:程序能够进行运算调度的最小单元,一个进程可以包含多个线程。
  3. 同步:只能在当前线程按先后顺序依次执行,不开启新线程,在完成了它预定的任务后才返回。
  4. 异步:可以在当前线程开启多个新线程执行,执行的顺序无法保证,会立即返回,预定的任务会完成但不会等它完成。因此,一个异步函数不会阻塞当前线程去执行下一个函数。
  5. 并行:对于多核CPU来说,可以在同一时间执行多个任务。对于单核的CPU来说,是在很短的时间片段轮询执行,让人感觉是同时执行。
  6. 串行:线程执行只能依次逐一先后有序的执行。
  7. 队列:GCD 提供有 dispatch queues 来处理代码块,这些队列管理你提供给 GCD 的任务并用 FIFO 顺序执行这些任务。这就保证了第一个被添加到队列里的任务会是队列中第一个开始的任务,而第二个被添加的任务将第二个开始,如此直到队列的终点。队列分为串行队列和并行队列,串行队列(Serial Queus)串行队列中的任务一次执行一个,每个任务只在前一个任务完成时才开始。而且,你不知道在一个 Block 结束和下一个开始之间的时间长度。并发队列(Concurrent Queus):在并发队列中的任务能得到的保证是它们会按照被添加的顺序开始执行,任务可能以任意顺序完成,你不会知道何时开始运行下一个任务,或者任意时刻有多少 Block 在运行。
  • 队列和任务的特点

  队列以先进先出的方式进行任务的调度,当轮到某个任务执行的时候,从队列取出,交给一个线程去执行。

  1. 串行队列:任务按照添加的顺序被调度,当前任务不执行完毕,不会进行下次任务的调度。
  2. 并行队列:只要有空闲的线程,队列就会调度当前任务,交给线程去执行,不需要考虑前面是都有任务在执行,只要有线程可以利用,队列就会调度任务。
  3. main队列:是一个串行队列,主要用于UI更新相关的任务。
  4. global队列:全局队列是一个并行队列。
  5. 同步任务:不会开新线程,任务一个接着一个执行。
  6. 异步任务:会新开线程,任务可以并发执行。
  • 任务和队列组合
  1. 串行队列同步任务:组合特点串行队列顺序执行,同步任务不会开新线程,所以是one-by-one。
dispatch_queue_t serialQueue = dispatch_queue_create("com.gcd.demo", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(serialQueue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"任务1");
    });
    
    dispatch_sync(serialQueue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"任务2");
    });
    
    dispatch_sync(serialQueue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"任务3");
    });
    
    dispatch_sync(serialQueue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"任务4");
    });

  打印如下:

  2016-08-04 15:42:53.334 GCDTestDemo[6858:1582521] 任务1

  2016-08-04 15:42:54.342 GCDTestDemo[6858:1582521] 任务2

  2016-08-04 15:42:56.348 GCDTestDemo[6858:1582521] 任务3

  2016-08-04 15:42:57.353 GCDTestDemo[6858:1582521] 任务4

  2.串行队列异步任务:串行队列当前任务没有结束,不会进行下次调度。异步任务会在另一个线程上one-by-one的执行。

  执行结果如下

  技术分享

   3.并行队列同步任务:并行队列不用等待当前任务,只要有线程,就会调度下一个任务,同步任务不会开启新的线程,所以组合后还是one-by-one的执行。

  

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self testSerialQueue];
        NSLog(@"%@",[NSThread currentThread]);
    });

 

dispatch_queue_t serialQueue = dispatch_queue_create("com.gcd.demo", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_sync(serialQueue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"任务1 %@",[NSThread currentThread]);
    });
    
    dispatch_sync(serialQueue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"任务2 %@",[NSThread currentThread]);
    });
    
    dispatch_sync(serialQueue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"任务3 %@",[NSThread currentThread]);
    });
    
    dispatch_sync(serialQueue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"任务4 %@",[NSThread currentThread]);
    });

  执行结果:

2016-08-04 18:03:52.823 GCDTestDemo[7064:1618448] 任务1 <NSThread: 0x14d47590>{number = 3, name = (null)}

2016-08-04 18:03:53.827 GCDTestDemo[7064:1618448] 任务2 <NSThread: 0x14d47590>{number = 3, name = (null)}

2016-08-04 18:03:55.832 GCDTestDemo[7064:1618448] 任务3 <NSThread: 0x14d47590>{number = 3, name = (null)}

2016-08-04 18:03:58.838 GCDTestDemo[7064:1618448] 任务4 <NSThread: 0x14d47590>{number = 3, name = (null)}

2016-08-04 18:03:58.838 GCDTestDemo[7064:1618448] <NSThread: 0x14d47590>{number = 3, name = (null)}

  4.并行队列异步任务:再上一条中说明了并行队列的特点,而异步执行是任务可以开启新的线程,所以这中组合可以实现任务的并发,再实际开发中也是经常会用到的。

  

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self testSerialQueue];
        NSLog(@"%@",[NSThread currentThread]);
    });

 

- (void)testSerialQueue
{
    dispatch_queue_t serialQueue = dispatch_queue_create("com.gcd.demo", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(serialQueue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"任务1 %@",[NSThread currentThread]);
    });
    
    dispatch_async(serialQueue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"任务2 %@",[NSThread currentThread]);
    });
    
    dispatch_async(serialQueue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"任务3 %@",[NSThread currentThread]);
    });
    
    dispatch_async(serialQueue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"任务4 %@",[NSThread currentThread]);
    });
}

   执行结果:

2016-08-04 18:07:39.746 GCDTestDemo[7069:1619191] <NSThread: 0x15e56cf0>{number = 2, name = (null)}

2016-08-04 18:07:40.752 GCDTestDemo[7069:1619197] 任务2 <NSThread: 0x15d7dd00>{number = 3, name = (null)}

2016-08-04 18:07:41.752 GCDTestDemo[7069:1619196] 任务3 <NSThread: 0x15d514f0>{number = 4, name = (null)}

2016-08-04 18:07:42.751 GCDTestDemo[7069:1619198] 任务1 <NSThread: 0x15d79b90>{number = 5, name = (null)}

2016-08-04 18:07:42.752 GCDTestDemo[7069:1619199] 任务4 <NSThread: 0x15d644e0>{number = 6, name = (null)}

    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

iOS GCD 的理解 (一)

标签:

原文地址:http://www.cnblogs.com/yzvictory/p/5735520.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!