600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > GCD(Grand Central Dispatch)

GCD(Grand Central Dispatch)

时间:2021-05-02 10:26:40

相关推荐

GCD(Grand Central Dispatch)

1. GCD: 异步执行任务的技术之一,一般是将应用程序中记述的线程管理用代码在系统级实现,由于是系统级的管理,这样的话将有更好的线程效率。

2. 使用方法如下:

dispatch_async(queue, ^{// 想执行的任务});

开发者要做的只是定义想执行的任务并追加到适当的Dispatch Queue中。

3. 线程(Thread): 1个CPU执行的CPU指令列为一条无分叉路径。

4. Dispatch Queue分为两种:

a. Serial Dispatch Queue: 线性执行的线程队列,遵循FIFO(First In First Out)原则;

b. Concurrent Dispatch Queue: 并发执行的线程队列,并发执行的处理数取决于当前状态。

// 线性执行线程队列dispatch_queue_t serialQueue = dispatch_queue_create("com.mark.serialQueue", NULL);dispatch_async(serialQueue, ^{NSLog(@"block on serialQueue");});dispatch_release(serialQueue);// 并发执行线程队列dispatch_queue_t concurrentQueue = dispatch_queue_create("com.mark.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);dispatch_async(concurrentQueue, ^{NSLog(@"block on concurrentQueue");});dispatch_release(concurrentQueue);

5. 系统的Dispatch Queue:

a. Main Dispatch Queue: 主线程队列(Serial Queue), 在程序的RunLoop中执行。

b. Global Dispatch Queue: 系统中所有应用程序共用的全局队列(Concurrent Queue), 一般不必创建新的Dispatch Queue,使用此Queue就可以了。

Global Diapacth Queue有4个优先级:High Priority(高)、Default Priority(默认)、Low Priority(低)、Background Priority(后台)。

// 获取Main Dispatch Queuedispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();// 获取Global Dispatch Queuedispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);dispatch_queue_t globalDispatchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_queue_t globalDispatchQueueLow = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);// 常用示例dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{// 可执行并发处理dispatch_async(dispatch_get_main_queue(), ^{// 执行主线程更新操作 });});

6. 关于自定义生成的Dispatch Queue优先级:首先dispatch_queue_create()生成的Dispatch Queue与默认Global Dispatch Queue具有相同的Priority,要改变Dispatch Queue的优先级则要使用dispatch_set_target_queue函数:

// 改变serialQueue(Default Priority)优先级为Background Prioritydispatch_queue_t serialQueue = dispatch_queue_create("com.mark.serialQueue", NULL);dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);dispatch_set_target_queue(serialQueue, globalDispatchQueueBackground);

7. Dispatch Queue的延迟执行:dispatch_after():

// 2秒后将指定的Block增加到指定的Dispatch Queue中double delayInSeconds = 2.0;dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));dispatch_after(popTime, dispatch_get_main_queue(), ^(void){NSLog(@"Waitted at least 2 seconds");});

8. 多个Dispatch Queue执行结束后的执行操作: Dispatch Group

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_group_t group = dispatch_group_create();dispatch_group_async(group, queue, ^{NSLog(@"Queue One");});dispatch_group_async(group, queue, ^{NSLog(@"Queue Two");});dispatch_group_async(group, queue, ^{NSLog(@"Queue Three");});dispatch_group_notify(group, dispatch_get_main_queue(), ^{NSLog(@"Queues Done");});// 也可以这样执行,每二参数用于表示超时时间//dispatch_group_wait(group, DISPATCH_TIME_FOREVER);dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1ull *NSEC_PER_SEC);long result = dispatch_group_wait(group, time);if (0 == result) {// 属于Dispatch Group的全部处理执行结束}else {// 属于Dispatch Group的某一个处理在超过指定时限后还在执行中}dispatch_release(group);

// 不过还是提推荐使用dispatch_group_notify

9. 关于读写的数据同步操作,为处理数据而作:dispatch_barrier_async()

dispatch_queue_t queue = dispatch_queue_create("com.mark.queue", DISPATCH_QUEUE_CONCURRENT);dispatch_async(queue, bk_0_for_reading);dispatch_async(queue, bk_1_for_reading);dispatch_async(queue, bk_2_for_reading);dispatch_async(queue, bk_3_for_reading);// 以上的并发队列中执行的都是读任务,并不涉及到数据冲突问题(数据可以被多线程同时读取,并发用于提高效率,并不影响数据)// 接下就是要写入数据后再执行相关的下半部的并发队列任务dispatch_barrier_async(queue, bk_for_writing);// 继续下半部分的并发dispatch_async(queue, bk_4_for_reading);dispatch_async(queue, bk_5_for_reading);dispatch_async(queue, bk_6_for_reading);

10. 可控制dispatch_async Block块执行次数的Block API: dispatch_apply()

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_apply(10, queue, ^(size_t index){NSLog(@"%zu", index);});// Param1 : Block执行次数// Param2 : Block追回的队列// Param3 : Block执行的次数索引// 高效遍历数据元素(无序遍历)dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_apply([array count], queue, ^(size_t index){NSLog(@"array element of index %d: %@", index, [array objectAtIndex:index]);});

11. 线程队列的挂起与执行:

// 挂起队列dispatch_suspend(queue);// 恢复队列执行dispatch_resume(queue);

12. 更细粒度的排他控制:dispatch_semaphore

1 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);2 // Create dispatch_semaphore3 // semaphore value初始化为14 // 保证可访问NSMutableArray类对象的线程同时只有一个5 dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);6 NSMutableArray *array = [[NSMutableArray alloc] init];7 for (int i = 0; i < 100000; i++) {8dispatch_async(queue, ^{9 // Waiting for dispatch semaphore, 直到semaphore值达到大于等于110 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);11 // 由于Dispatch semaphore的计数值达到大于等于112 // 所以将Dispatch semaphore的计数值减113 // dispatch_semaphore_wait函数执行返回14 // 即执行到此时的Dispatch semaphore计数值恒为015 // 由于可访问NSMutableArray类对象的线程只有一个16 // 因此可安全进行更新17 [array addObject:[NSNumber numberWithInt:i]];18 // 排他控制处理结束19 // 所以通过dispatch_semaphore_signal函数20 // 将Dispatch semaphore的计数值加121 // 如果有通过dispatch_semaphore_wait函数等待Dispatch semaphore的22 // 计数值增加的线程,由最先等待的线程执行23 dispatch_semaphore_signal(semaphore);24});25 }26 dispatch_release(semaphore);

13. dispatch_once: 只执行一次指定处理的API

// dispatch_once函数简化如下static int initialized = NO;if (NO == initialized) {// 初始化 initialized = YES;}// dispatch_once函数使用如下static dispatch_once_t pred;dispatch_once(&pred, ^{// 初始化,这里多用于单例的模式});

14. Dispatch I/O:并发读取文件数据,高效率读取文件:

// 并发读取文件原理dispatch_async(queue, ^{/* 读取0-8191字节*/});dispatch_async(queue, ^{/* 读取8192-16383字节*/});dispatch_async(queue, ^{/* 读取163784-24575字节*/});dispatch_async(queue, ^{/* 读取24576-32767字节*/});dispatch_async(queue, ^{/* 读取32768-40959字节*/});dispatch_async(queue, ^{/* 读取40960-49151字节*/});dispatch_async(queue, ^{/* 读取49152-57343字节*/});dispatch_async(queue, ^{/* 读取57344-65535字节*/});// 实例代码如下dispatch_queue_t pipe_q = dispatch_queue_create("PipQ", NULL);dispatch_io_t pipe_channel = dispatch_io_create(DISPATCH_IO_STREAM, fd, pip_q, &(int err){close(fd);});*out_fd = dfpair[1];// 设定函数一次读取的大小(分割大小)dispatch_io_set_low_water(pipe_channel, SIZE_MAX);dispatch_io_read(pipe_channel, 0, SIZE_MAX, pipe_q, ^{if (0 == err) {size_t len = dispatch_data_get_size(pipedata);if (len > 0) {const char *bytes = NULL;char *encoded;dispatch_data_t md = dispatch_data_create_map(pipedata, (const void **)&bytes, &len);encoded = asl_core_encode_buffer(bytes, len);asl_set((aslmsg)merged_msg, ASL_KEY_AUX_DATA, encoded);free(encoded);_asl_send_message(NULL, merged_msg, -1, NULL);_asl_msg_release(merged_msg);dispatch_release(md);}}if (done) {dispatch_semaphore_signal(sem);dispatch_release(pipe_channel);dispatch_release(pipe_q);}});

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。