• iOS多线程之4.GCD简介


    GCD(Grand Central Dispatch)应该是我们开发中最常用到的多线程解决方案,是苹果公司专门为多核的并行运算提出的解决方案,是基于C语言的,提供了很多非常强大的函数。

    GCD的优势

    1.会自动利用更多的CPU内核(从iPhone4s开始是双核,iPhone7系列是4核)。
    2.会自动管理线程的创建、生命周期、销毁等,不需要写一句关于线程的代码。
    3.将任务添加到队列中,GCD会自动从队列中将任务取出,放到对应的线程中执行。

    进程与线程

    1.简单点说一个APP就是一个进程,例如微信、迅雷都分别是一个进程。
    2.一个进程可以拥有多条线程。当我们打开APP时系统会自动帮我们创建一条主线程,当我们要让APP干点别的事时,例如刷新数据,就要开启一条子线程来向服务器请求数据,所以一个进程可以拥有多条线程。(并不是让APP干什么事,都会开启子线程,这里只是为了解释方便,才这么说的。)
    20161029092719352.png

    队列(queue)

    队列就是用来存放任务的,任务就是我们让APP干的事,例如下载图片,刷新数据等,都是任务。我们使用GCD,只要把任务放到队列中就可以了,系统会自动帮我们创建线程,调度任务。任务的调度原则遵行FIFO原则,就是哪个任务先放进队列中,就先执行。队列分为串行队列,和并行(并发)队列。
    1.串行队列 : 就是队列里的任务必须一个一个往下执行。例如我们要执行A、B、C 三个任务,我们把这三个任务放到串行队列中,必须是A执行完,B才执行,B执行完C才执行。
    创建串行队列有两种方法:
    (1)自定义队列
    代码:

     // 创建串行队列
        dispatch_queue_t queue = dispatch_queue_create("doujiangyoutiao", DISPATCH_QUEUE_SERIAL);
        // 添加任务A
        dispatch_async(queue, ^{
            NSLog(@"执行任务A");
        });
        // 添加任务B
        dispatch_async(queue, ^{
            NSLog(@"执行任务B");
        });
        // 添加任务C
        dispatch_async(queue, ^{
            NSLog(@"执行任务C");
        });
    

    日志

    2016-11-04 14:00:06.546 TTTTTTTTTT[11059:128030] 执行任务A
    2016-11-04 14:00:06.546 TTTTTTTTTT[11059:128030] 执行任务B
    2016-11-04 14:00:06.547 TTTTTTTTTT[11059:128030] 执行任务C
    

    1)“doujiangyoutiao”是这个队列的名字;
    2)DISPATCH_QUEUE_SERIAL表示创建的是一条串行对列。
    (2)主队列
    dispatch_queue_t queue =dispatch_get_main_queue();
    得到主队列,主队列是串行队列,主队列中的任务默认都在主线程中执行。
    2.并行队列:就是队列里的任务可以一齐执行。还是举执行A、B、C 三个任务的例子。我们把三个任务放到并行队列中,这三个任务可以一起执行,所以不一定谁先下载完。串行队列里一定是A先下载完。
    代码:

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 创建并行队列
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        // 添加任务A
        dispatch_async(queue, ^{
            NSLog(@"执行任务A");
        });
        // 添加任务B
        dispatch_async(queue, ^{
            NSLog(@"执行任务B");
        });
        // 添加任务C
        dispatch_async(queue, ^{
            NSLog(@"执行任务C");
        });
    }
    

    每次打印的日志应该都不一样,有兴趣可以多试几次。

    2016-11-04 14:09:03.871 TTTTTTTTTT[11356:131391] 执行任务B
    2016-11-04 14:09:03.871 TTTTTTTTTT[11356:131393] 执行任务C
    2016-11-04 14:09:03.871 TTTTTTTTTT[11356:131390] 执行任务A
    

    创建并行队列有两种方法:
    (1)看上面代码得到全局并行队列,不需要我们创建,我们一般用这个。第一个参数表示这个队列的优先级
    (DISPATCH_QUEUE_PRIORITY_HIGH、DISPATCH_QUEUE_PRIORITY_DEFAULT、DISPATCH_QUEUE_PRIORITY_LOW、DISPATCH_QUEUE_PRIORITY_BACKGROUND),用第二个就可以。第二个参数还没开发出来,没有用,默认写0即可。
    (2)自定义队列
    dispatch_queue_t queue=dispatch_queue_create("fuhang",DISPATCH_QUEUE_CONCURRENT);
    "fuhang"为并发队列的名字,后面表示创建的队列为并行队列。

    注意:

    1. 并发队列里的任务一定会一起执行嘛?
      答:肯定不会啊。如果并发队列里有100个任务,一起执行就得创建100条线程,那不得累死CPU啊!任务少了会一起执行,任务多了对先一起执行一部分。
    2. 线程并发???
      答:错。串行并发是形容队列的!!!线程没有,线程里的任务都是一个一个的往下执行,不可能多个任务一起执行。

    同步和异步

    同步:会堵塞当前线程,队列里的任务执行完,任务所在的线程才会往下执行。其实说白了就是插队。
    dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
    第一个参数是队列,第二个参数是要往队列里添加的任务。

    20161029093326640.png
      异步:不会堵塞当前线程。
    dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
    同上。
      同步和异步就是用来判断是否要在当前线程的基础上创建新的线程。同步不会创建新的线程,队列里的任务在当前线程中执行,所以会堵塞当前线程。但是异步也不是一定会创建新的线程,这要根据CPU的使用情况来看,但是大多数情况会创建一个线程。

  • 相关阅读:
    数组实现栈
    栈应用实例单词逆序
    使用JXMapViewer将地图集成到swing app中
    使用xbee连接地面站和飞控
    QWT编译、配置、使用(Qt Creator)
    Qt跨线程调用错误解析及解决办法
    SVN版本服务器搭建(服务端+客户端)
    opencv配置过程 (cmake,vs2013,qt 5.4)
    基数排序/Go实现
    c/c++ 编译器内存对齐问题
  • 原文地址:https://www.cnblogs.com/doujiangyoutiao/p/6030150.html
Copyright © 2020-2023  润新知