GCD 中同步、异步、串行、并行

2018-06-20  本文已影响0人  iOS扫地僧

串行队列 VS 并行队列

GCD 中的队列是用来放置需要执行的任务的,任务的取出遵循队列的先进先出的原则。
GCD 将队列中的任务取出,并放置到对应的线程中执行。

串行队列:同一时刻只有一个任务在执行,后面的任务需要等待正在执行的任务结束,才能执行。
并行队列:同一时刻可以有多个任务在执行,后面的任务不需等待,只要有可以执行任务的线程,就可以执行。其中,执行任务的线程数量取决于当前系统的状态,包括处理数、CPU核数、CPU负荷等系统状态。

同步派发 VS 异步派发

派发指的是将任务追加到指定的队列中,等待 GCD 取出执行。
同步派发 dispatch_sync:一个任务的追加会等待当前任务执行完,再进行。同步,保证了任务执行的顺序。
异步派发 dispatch_async:一个任务的追加不等待当前任务执行完,直接追加在队列中。因为任务的追加不等待,直接追加,也就需要 GCD 为其开启新线程来执行操作。

下面将分为四步分别测试:

同步派发串行队列

//同步派发串行队列
- (void)syncSERIAL
{
    dispatch_queue_t serQueue = dispatch_queue_create("zn.serQueue", DISPATCH_QUEUE_SERIAL);
    for (int i=0; i<10; i++) {
        dispatch_sync(serQueue, ^{
            NSLog(@"时间在:%@进行第:%d个输出  %@ \n",[[NSDate date] description],i,[NSThread currentThread]);
            sleep(1);
        });
    }
}
image.png

异步派发串行队列

//异步派发串行队列
- (void)asyncSERIAL
{
    dispatch_queue_t serQueue = dispatch_queue_create("zn.serQueue", DISPATCH_QUEUE_SERIAL);
    for (int i=0; i<10; i++) {
        dispatch_async(serQueue, ^{
            NSLog(@"时间在:%@进行第:%d个输出  %@ \n",[[NSDate date] description],i,[NSThread currentThread]);
            sleep(1);
        });
    }
}
image.png

同步派发并行队列

//同步派发并行队列
- (void)syncConcurrent
{
    dispatch_queue_t conQueue = dispatch_queue_create("zn.conQueue", DISPATCH_QUEUE_CONCURRENT);
    for (int i=0; i<10; i++) {
        dispatch_sync(conQueue, ^{
            NSLog(@"时间在:%@进行第:%d个输出  %@ \n",[[NSDate date] description],i,[NSThread currentThread]);
            sleep(1);
        });
    }
}
image.png

异步派发并行队列

//异步派发并行队列
- (void)asyncConcurrent
{
    dispatch_queue_t conQueue = dispatch_queue_create("zn.conQueue", DISPATCH_QUEUE_CONCURRENT);
    for (int i=0; i<10; i++) {
        dispatch_async(conQueue, ^{
            NSLog(@"时间在:%@进行第:%d个输出  %@ \n",[[NSDate date] description],i,[NSThread currentThread]);
            sleep(1);
        });
    }
}
image.png

注意:此时的输出偶尔可能是有序的,但多测试几次就会发现,此时是异步执行,同时执行,输出顺序是无需的。

总结:

同步派发,因为要等待当前任务的进行,所以不需要开启新线程;
异步派发,因为不需等待当前任务,可以开启新线程执行任务。

串行队列,任务一个一个进行,在一条线程中即可完成;
并行队列,可同时进行多个任务,会在多条线程中进行。

注意:有兴趣的同学可以试试把上面的4个代码混合调用(同步串行、同步并行、异步串行、异步并行交叉使用)或许会发现新大陆哟!在这先不做赘述

下面的这句话可能更容易理解:

dispatch_ async将block追加在队列中,不做等待立即执行block中的操作--异步    
串行队列:按序执行
并行队列:立即执行

dispatch_ sync将block追加在队列中,按顺序执行,后面的操作需要等待前面的操作执行完--同步
串行队列:按序执行
并行队列:按序执行

本文部分内容转载自:https://yiweifen.com/html/news/WaiYu/101972.html

上一篇 下一篇

猜你喜欢

热点阅读