Grand Central Dispatch(一)

孙福
2023-12-01
  • OS X 和 iOS 提供了几种不同的 API 来支持并发编程。每一个 API 都具有不同的功能和使用限制,这使它们适合不同的任务。

    实际上,并发编程是一个很有挑战的主题,它有许多错综复杂的问题和陷阱。
    OS X 和 iOS 提供了几种不同的 API 来支持并发编程。每一个 API 都具有不同的功能和使用限制,这使它们适合不同的任务。同时,这些 API 处在不同的抽象层级上。
    在os X 和iOS 中苹果提供了几种,Pthread、NShread、GCD,在这篇文章中只介绍GCD。

    What is GCD?

    GCD is the marketing name for libdispatch, Apple’s library that provides support for concurrent code execution on multicore hardware on iOS and OS X. It offers the following benefits:

    • GCD can improve your app’s responsiveness by helping you defer computationally expensive tasks and run them in the background.
    • GCD provides an easier concurrency model than locks and threads and helps to avoid concurrency bugs.
    • GCD can potentially optimize your code with higher performance primitives for common patterns such as singletons.

    GCD 是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统中实现。开发者只需要定义想执行的任务并追加到适当的Dispatch Queue 中,GCD就能生成必要的线程并执行任务。由于线程管理是作为系统的一部分来实现的。因此可统一管理,也可执行任务,这样就比以前的线程更有效率了。

    GCD 用我们难以置信的非常简洁的方式实现了极为复杂繁琐的多线程编程。例如:

    dispatch_async(dispatch_get_main_queue(), ^{


            });

    仅此一行代码,便能让处理在主线程中执行。

    可能在开发中我们也经常使用

    [selfperformSelectorOnMainThread:@selector(doneWork)withObject:nilwaitUntilDone:NO];

    [selfperformSelector:@selector(doSomeWork)withObject:nil];

    performSelector 虽然比NSThread 类进行多线程简单的多。但是相对于GCD ,便一目了然。而且,GCD提供的系统级别线程管理更能提高执行效率。

    使用GCD 非常的方便。如下

    dispatch_async(queue, ^{


            });

    block中使我们想执行的任务。但这个queue又是什么呢。

    dispatch queue 是执行处理的等待队列,有两种dispatch queue ,一种是等待现在执行中处理的serial dispatch queue,另一种是不等待现在执行中处理的concurrent dispatch queue。

    在苹果文档中是这样描述的:

    • DISPATCH_QUEUE_SERIAL

      A dispatch queue that executes blocks serially in FIFO order.

    • DISPATCH_QUEUE_CONCURRENT

      A dispatch queue that executes blocks concurrently. Although they execute blocks concurrently, you can use barrier blocks to create synchronization points within the queue. 


    如下面示例:

    dispatch_async(queue, blk0);

    dispatch_async(queue, blk0);

    dispatch_async(queue, blk0);

    dispatch_async(queue, blk0);

    dispatch_async(queue, blk0);


    如果queue 为serial dispatch queue 时 ,因为要等待执行中的处理结束,因此执行顺序一定为blk0,blk1,blk2...,若queue 为concurrent dispatch queue 时,因为不需要等待处理结束,因此,首先执行blk0 而不管blk0 是否结束,都开始执行后面的blk1,如此循环。最后执行结束的时间顺序是不一定的。

  • 现在我们知道有serial dispatch queue  和 concurrent dispatch queue 两种,但是如何才能得到dispatch queue 呢。方法有两种

    dispatch_queue_t serialQueue =dispatch_queue_create("com.example.gcd.serialQueue",NULL);


    dispatch_queue_t concurrentQueue =dispatch_queue_create("com.example.gcd.concurrentQueue",DISPATCH_QUEUE_CONCURRENT);


    虽然可以生成多个dispatch queue ,但是dispatch queue 是要占用系统资源的,因此在使用多线程编程的时候,除了生成所必须的数量外,最好不要一激动就生成大量的serial dispatch queue。

  • 当我们想要更新文件1个文件 或是一个文件是可以分割的一个文件块时,生成一个serial dispatch queue。当想并行执行不发生数据竞争等问题的处理时,使用concurrent dispatch queue,而且对于concurrent dispatch queue来说,不管生成多少,由于xnu 内核只使用有效管理的线程。因此不会发生serial dispatch queue 的问题。


    上面说了第一种生成dispatch queue 的方法。

    第二种是获取系统标准提供的dispatch queue

    实际上不用特意去生成dispatch queue,系统本身就提供了几个。main dispatch queue 和global dispatch queue。


    Main Dispatch Queue                                 serial dispatch queue

    Global Dispatch Queue(High Priority)                Concurrent dispatch queue 

    Global Dispatch Queue(Default Priority)             Concurrent dispatch queue

    Global Dispatch Queue(Low Priority)                 Concurrent dispatch queue

    Global Dispatch Queue(Background Priority)          Concurrent dispatch queue

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

    /**

     *  可并行执行的处理

     */

            });

    当然,本文也只是介绍及使用,并没有深入探究。
    站在巨人的肩上



 类似资料: