GCD
发表时间:2020-10-19
发布人:葵宇科技
浏览次数:25
dispatch_group
如不雅想在dispatch_queue中所有的义务履行完成后在做某种操作,在串行队列中,可以把该操作放到最后一个义务履行完成后持续,然则在并行队列中怎么做呢。这就有dispatch_group 成组操作。比如
[img]http://common.cnblogs.com/images/copycode.gif
dispatch_queue_t dispatchQueue = dispatch_queue_create("ted.queue.next", DISPATCH_QUEUE_CONCURRENT); dispatch_group_t dispatchGroup = dispatch_group_create(); dispatch_group_async(dispatchGroup, dispatchQueue, ^(){ NSLog(@"dispatch-1"); }); dispatch_group_async(dispatchGroup, dispatchQueue, ^(){ NSLog(@"dspatch-2"); }); dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){ NSLog(@"end"); });
[img]http://common.cnblogs.com/images/copycode.gif
膳绫擎的 log1 和log2输出次序不定,因为是在并行队列上履行,当场行队列全部履行完成后,最后到main队列上履行一个操作,包管“end”是最后输出。 别的,这里也可以不消创建本身的并行队列,用全局的global,那个也是个并行队列. dispatch_get_gloable_queue(0,0);
dispatch_barrier_async
先看段代码
[img]http://common.cnblogs.com/images/copycode.gif
dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-1"); }); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-2"); }); dispatch_barrier_async(concurrentQueue, ^(){ NSLog(@"dispatch-barrier"); }); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-3"); }); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-4"); });
[img]http://common.cnblogs.com/images/copycode.gif
dispatch_barrier_async 感化是在并行队列中,等待前面两个操作并行操作完成,这里是并行输出
dispatch-1,dispatch-2
然后履行
dispatch_barrier_async中的操作,(如今就只会履行章一操作)履行完成后,即输出
"dispatch-barrier, 最后该并行队列恢答复复兴有履行状况,持续并行履行
dispatch-3,dispatch-4
dispatch_async 和dispatch_sync
dispatch_sync(),同步添加操作。他是等待添加进队列琅绫擎的操作完成之后再持续履行。
[img]http://common.cnblogs.com/images/copycode.gif
dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT); NSLog(@"1"); dispatch_sync(concurrentQueue, ^(){ NSLog(@"2"); [NSThread sleepForTimeInterval:10]; NSLog(@"3"); }); NSLog(@"4"); 输出 :
11:36:25.313 GCDSeTest[544:303] 1
11:36:25.313 GCDSeTest[544:303] 2
11:36:30.313 GCDSeTest[544:303] 3//模仿长时光操作
11:36:30.314 GCDSeTest[544:303] 4
[img]http://common.cnblogs.com/images/copycode.gif
dispatch_async ,异步添加进义务队列,它不会做任何等待
[img]http://common.cnblogs.com/images/copycode.gif
dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT); NSLog(@"1"); dispatch_async(concurrentQueue, ^(){ NSLog(@"2"); [NSThread sleepForTimeInterval:5]; NSLog(@"3"); }); NSLog(@"4"); 输出:
11:42:43.820 GCDSeTest[568:303] 1
11:42:43.820 GCDSeTest[568:303] 4
11:42:43.820 GCDSeTest[568:1003] 2
11:42:48.821 GCDSeTest[568:1003] 3//模仿长时光操作时光
[img]http://common.cnblogs.com/images/copycode.gif
dispatch_apply
dispathc_apply 是dispatch_sync 和dispatch_group的接洽关系API.它以指定的次数将指定的Block参加到指定的队列中。并等待队列中操作全部完成.
[img]http://common.cnblogs.com/images/copycode.gif
NSArray *array = [NSArray arrayWithObjects:@"/Users/chentao/Desktop/copy_res/gelato.ds", @"/Users/chentao/Desktop/copy_res/jason.ds", @"/Users/chentao/Desktop/copy_res/jikejunyi.ds", @"/Users/chentao/Desktop/copy_res/molly.ds", @"/Users/chentao/Desktop/copy_res/zhangdachuan.ds", nil]; NSString *copyDes = @"/Users/chentao/Desktop/copy_des"; NSFileManager *fileManager = [NSFileManager defaultManager]; dispatch_async(dispatch_get_global_queue(0, 0), ^(){ dispatch_apply([array count], dispatch_get_global_queue(0, 0), ^(size_t index){ NSLog(@"copy-%ld", index); NSString *sourcePath = [array objectAtIndex:index]; NSString *desPath = [NSString stringWithFormat:@"%@/%@", copyDes, [sourcePath lastPathComponent]]; [fileManager copyItemAtPath:sourcePath toPath:desPath error:nil]; }); NSLog(@"done"); });
[img]http://common.cnblogs.com/images/copycode.gif
输出 copy-index 次序不肯定,因为它是并行履行的(dispatch_get_global_queue是并行队列),然则done是在以上拷贝操作完成后才会履行,是以,它一般都是放在dispatch_async琅绫擎(异步)。实际上,这里 dispatch_apply如不雅换成串行队列上,则会依次输出index,但如许违背了我们想并行进步履行效力的初志。
dispatch_semaphore
dispatch_semaphore 旌旗灯号量基于计数器的一种多线程同步机制。在多个线查拜访共有资本时刻,会因为多线程的特点而激发数据掉足的问题。
[img]http://common.cnblogs.com/images/copycode.gif
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
NSMutableArray *array = [NSMutableArrayarray];
for (int index = 0; index < 100000; index++) {
dispatch_async(queue, ^(){
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//
NSLog(@"addd :%d", index);
[array addObject:[NSNumber numberWithInt:index]];
dispatch_semaphore_signal(semaphore);
});
}
[img]http://common.cnblogs.com/images/copycode.gif
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 如不雅semaphore计数大年夜于等于1.计数-1,返回,法度榜样持续运行。如不雅计数为0,则等待。这里设置的等待时光是一向等待。dispatch_semaphore_signal(semaphore);计数+1.在这两句代铝闼殇的履行代码,每次只会许可一个线程进入,如许就有效的包管了在多线程情况下,只能有一个线程进入。