iOS Developer程序员iOS 开发

多线程之GCD

2016-07-13  本文已影响116人  YvanLiu

简介

GCD:(Grand Central Dispatch)GCD是基于C语言的。
GCD本身是苹果公司为多核的并行运算提出的解决方案,它完全由系统管理线程,我们不需要编写线程代码,只需要在适当的调度队列中(dispatch queue)实现要执行的任务就好。GCD会负责创建线程和调度你的任务,系统直接提供线程管理。
GCD能推迟昂贵的计算任务,并在后台运行,从而可以改善工程的性能。
GCD能提供易于我们使用的并发模型从而帮我们避开并发陷阱。

调度队列(dispath queue)

queue 是GCD的一个重要概念,我们可以这样理解:我们要执行一个长期任务,可以将这个任务分成多个工作单元,并将这些工作单元添加到dispath queue 中,系统则会为我们管理这些工作单元,,为我们在多个线程上执行工作单元,我们不需要直接启动和管理后台线程。
GCD的dispach queue 是严格按照先进先出的的原则工作的,添加到dispath queue的工作单元将始终按照加入dispath queue的顺序启动。

一、并行队列(concurrent dispath queue)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
DISPATCH_QUEUE_PRIORITY_HIGH 2      优先级最高
DISPATCH_QUEUE_PRIORITY_DEFAULT 0   优先级默认
DISPATCH_QUEUE_PRIORITY_LOW (-2)    优先级最低

二、串行队列(serial dispatch queue)

dispatch_queue_t queue = dispatch_queue_create("cn.test.queue", NULL);
第一个参数是queue的名字
第二个参数是一组queue的属性

三、同步&异步

    NSLog(@"当前线程:%@", [NSThread currentThread]);
    //创建一个并发线程
    dispatch_queue_t queue;
    queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    //创建一个异步任务
    dispatch_async(queue, ^{
        NSLog(@"异步任务,当前线程:%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"同步任务,当前线程:%@",[NSThread currentThread]);
    });
打印消息:
当前线程:<NSThread: 0x7fb102508120>{number = 1, name = main}
异步任务,当前线程:<NSThread: 0x7fb102782970>{number = 2, name = (null)}
同步任务,当前线程:<NSThread: 0x7fb102508120>{number = 1, name = main}

四、循环迭代(dispatch_apply)

    queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    //你传递的block必须包含一个size_t类型的参数,用来标识当前循环迭代。第一次迭代这个参数值为0,最后一次值为count - 1
    size_t count = 8;
    dispatch_apply(count, queue, ^(size_t t) {
        NSLog(@"%zu",t);
    });
打印结果:
2016-07-13 11:10:33.423 GCDTest[1867:83704] 0
2016-07-13 11:10:33.423 GCDTest[1867:83703] 2
2016-07-13 11:10:33.423 GCDTest[1867:83662] 1
2016-07-13 11:10:33.423 GCDTest[1867:83714] 3
2016-07-13 11:10:33.423 GCDTest[1867:83704] 4
2016-07-13 11:10:33.424 GCDTest[1867:83703] 5
2016-07-13 11:10:33.424 GCDTest[1867:83662] 6
2016-07-13 11:10:33.424 GCDTest[1867:83714] 7

由此可见,这些迭代是并发执行的,并且顺序不固定,

五、暂停和继续queue

    NSLog(@"当前线程:%@", [NSThread currentThread]);
    //创建一个串发线程
    dispatch_queue_t queue;
    queue = dispatch_queue_create("cn.test.queue", NULL);
    dispatch_async(queue, ^{
        NSLog(@"异步任务,当前线程:%@",[NSThread currentThread]);
    });
    //挂起queue
    dispatch_suspend(queue);
    dispatch_sync(queue, ^{
        NSLog(@"同步任务,当前线程:%@",[NSThread currentThread]);
    });
    //结束挂起
    dispatch_resume(queue);
打印结果
当前线程:<NSThread: 0x7fdb53d00550>{number = 1, name = main}

六、常用

//  后台执行:
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });
 // 主线程执行:
 dispatch_async(dispatch_get_main_queue(), ^{
      // something
 });

 // 一次性执行:
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
     // code to be executed once
 });

 // 延迟2秒执行:
 double delayInSeconds = 2.0;
 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
     // code to be executed on the main queue after delay
 });

 // 自定义dispatch_queue_t
 dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
 dispatch_async(urls_queue, ^{  
   // your code 
 });
// 销毁队列 
 dispatch_release(urls_queue);

 // 合并汇总结果
 dispatch_group_t group = dispatch_group_create();
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // 并行执行的线程一
 });
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // 并行执行的线程二
 });
 dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
      // 汇总结果
 });
dispatch_set_target_queue(dispatch_object_t object, dispatch_queue_t queue);
将需要执行的任务对象指定到不同的队列中去处理,比如说有两个队列dispatchA和dispatchB,这时把dispatchA指派到dispatchB:

七、一些概念

上一篇 下一篇

猜你喜欢

热点阅读