Grand Central Diaptch (GCD) 多线程编程

来源:互联网 发布:联想移动硬盘加密软件 编辑:程序博客网 时间:2024/05/29 19:59
作者:舍得333 主页:http://blog.sina.com.cn/u/1509658847
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出版、作者信息和本声明,否则将追究法律责任。


参考书籍: 《Objective-C高级编程 iOS与OS X多线程和内存管理》
书籍介绍连接:http://book.douban.com/subject/24720270/

1.
dispatch_async : 异步执行,意思就是,把参数里的block添加到queue后,函数就马上返回,继续执行下面的语句(不论该block是否执行完成。)
dispatch_sync : 同步执行,要把参数里的block添加到queue,要等待block执行完毕,函数才能返回执行下面的语句,否则,该线程就阻塞(卡死)在这条语句上(就像执行了sleep()一样)。所以,特别是在主线程上使用该方法要特别注意,block要执行很长时间的话,主线程就阻塞了。在其他线程也要注意,任何一个线程被阻塞都是很严重的问题。

2.这里分并行队列(concurrent dispatch queue)和串行队列(serial dispatch queue),这两个的区别不再赘述,请google。

2.1 队列的创建

    

    dispatch_queue_t serialQueue = dispatch_queue_create("com.test.firstqueue", NULL);//串行队列
    dispatch_queue_t concurrentQueue = dispatch_queue_create("com.test.firstqueue", DISPATCH_QUEUE_CONCURRENT);//并行队列
    
   
    
    dispatch_retain(serialQueue);
    dispatch_release(serialQueue);
    
    dispatch_release(serialQueue);
    dispatch_release(concurrentQueue);

2.2 系统提供的标准queue

主要分为2个
Main dispatch queue //主线程的队列,属于串行
Global dispatch queue  //子线程队列 ,属于并行队列

//Main dispatch queue 主线程的队列,属于串行
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    
   
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

注意:对这两个线程执行 retain,release 不会有任何效果。

2.3 设置队列的优先级
队列的优先级 与 队列的类型(并行、串行)无关
注意:不可以对上面两个系统提供的queue 设置优先级,否则会产生不可预测的结果
我们一般只对自己create的queue设置优先级

create生成的队列 都与global queue的默认级别相同。

    dispatch_queue_t subSerialQueue = dispatch_queue_create("com.test.setlevel", NULL);
    
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //设置第一个参数queue 与 第2个参数queue的优先级相同。注意,第一个queue ,不可以是系统提供的queue。
    dispatch_set_target_queue(subSerialQueue, globalQueue);

小窍门:
有多个串行队列,这些队列之间内部执行是按照串行,但是queue之间是并行,
将这多个串行队列 的优先级 全都设置为 同一个串行队列,那么这个queue之间也就变成串行执行的,以为他们属于同一优先级,没法并行。

3.dispatch_after

// dispatch_after
- (void)dispatchAfter{
    //在指定的时间后执行,即延迟**的时间执行
    
   
    dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC);
    
   
    dispatch_after(delayTime, dispatch_get_main_queue(), ^(void){
        NSLog(@"SW - dispatch_after");
    });
    
    //也可指定绝对时间执行,即指定某年某月某时执行
    //在1970 年后的1024*1024秒后 的那个时间点执行
    dispatch_time_t confirmTime = [self getDispatchTimeByDate:[NSDate dateWithTimeIntervalSince1970:(1024*1024)]];

    dispatch_after(confirmTime, dispatch_get_main_queue(), ^(void){
        NSLog(@"SW -dispatch_after confirmTime");
    });
    
}

// 取得dispatch_time_t格式的绝对时间点
- (dispatch_time_t)getDispatchTimeByDate:(NSDate *)date{
    NSTimeInterval interval;
    double second,subSecond;
    struct timespec time;
    dispatch_time_t milestone;
    
    interval = [date timeIntervalSince1970];
    subSecond = modf(interval, &second);
    time.tv_sec = second;
    time.tv_nsec = subSecond *NSEC_PER_SEC;
    milestone = dispatch_walltime(&time, 0);
    
    return milestone;
}

4.dispatch_group

在你需要将一组block 执行之后,再追加一个结束处理的block。
在serial queue实现很简单,只需要把“结束block”添加的队列的最后即可。
但是在concurrent queue里面就很那实现,因为你无法确定什么时候所有的block执行完,这时就需要 dispatch_group


- (void)dispatchGroupNotify{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_group_t group = dispatch_group_create();//注意create出来的group,要release
    
    //下面的添加的操作可以 不 在同一个queue内。
    dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_1");});
    dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_2");});
    dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_3");});
    
    //当 添加到组group的所有block完成,那么在主线程调用该block输出。
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"group_finish");});
    
    
    dispatch_release(group);
}

- (void)dispatchGroupWaitForever{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_group_t group = dispatch_group_create();//注意create出来的group,要release
    
    //下面的添加的操作可以 不 在同一个queue内。
    dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_1");});
    dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_2");});
    dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_3");});
    
   
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_release(group);
    
    
    
    
}

- (void)dispatchGroupWaitPartTime{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_group_t group = dispatch_group_create();//注意create出来的group,要release
    
    //下面的添加的操作可以 不 在同一个queue内。
    dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_1");});
    dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_2");});
    dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_3");});
    
   
    
    dispatch_time_t waitTime = dispatch_time(DISPATCH_TIME_NOW, 2ull*NSEC_PER_SEC);
    long resultCode = dispatch_group_wait(group, waitTime);
    dispatch_release(group);
}

0 0
原创粉丝点击