热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

dispatch_barrier_async、dispatch_apply、dispatch_block_notify、dispatch_group_notify

1、dispatch_barrier_asyncdispatch_barrier_async用于等待前面的任务执行完毕后自己才执行,而它后面的任务需等待它完成之后才执
  • 1、dispatch_barrier_async
  • dispatch_barrier_async用于等待前面的任务执行完毕后自己才执行,而它后面的任务需等待它完成之后才执行。一个典型的例子就是数据的读写,通常为了防止文件读写导致冲突,我们会创建一个串行的队列,所有的文件操作都是通过这个队列来执行,比如FMDB,这样就可以避免读写冲突。不过其实这样效率是有提升的空间的,当没有更新数据时,读操作其实是可以并行进行的,而写操作需要串行的执行,如何实现呢:

dispatch_queue_t queue = dispatch_queue_create("Database_Queue", DISPATCH_QUEUE_CONCURRENT);dispatch_async(queue, ^{NSLog(@"reading data1");});dispatch_async(queue, ^{NSLog(@"reading data2");});dispatch_barrier_async(queue, ^{NSLog(@"writing data1");[NSThread sleepForTimeInterval:1];});dispatch_async(queue, ^{[NSThread sleepForTimeInterval:1];NSLog(@"reading data3");});

执行结果如下:

GCDTests[13360:584316] reading data2
GCDTests[13360:584317] reading data1
GCDTests[13360:584317] writing data1
GCDTests[13360:584317] reading data3

我们将写数据的操作放在dispatch_barrier_async中,这样能确保在写数据的时候会等待前面的读操作完成,而后续的读操作也会等到写操作完成后才能继续执行,提高文件读写的执行效率。


  • 2、dispatch_apply
  • dispatch_apply类似一个for循环,会在指定的dispatch queue中运行block任务n次,如果队列是并发队列,则会并发执行block任务,dispatch_apply是一个同步调用,block任务执行n次后才返回。
    简单的使用方法:

dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT);
//并发的运行一个block任务5次
dispatch_apply(5, queue, ^(size_t i) {NSLog(@"do a job %zu times",i+1);
});
NSLog(@"go on");

输出结果:

GCDTests[10029:760640] do a job 2 times
GCDTests[10029:760640] do a job 1 times
GCDTests[10029:760640] do a job 3 times
GCDTests[10029:760640] do a job 5 times
GCDTests[10029:760640] do a job 4 times
GCDTests[10029:760640] go on

  • 3、dispatch_block_notify
  • dispatch_block_notify当观察的某个block执行结束之后立刻通知提交另一特定的block到指定的queue中执行,该函数有三个参数,第一参数是需要观察的block,第二个参数是被通知block提交执行的queue,第三参数是当需要被通知执行的block,函数的原型:

void dispatch_block_notify(dispatch_block_t block, dispatch_queue_t queue,dispatch_block_t notification_block);

具体使用的方法:

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);dispatch_block_t previousBlock = dispatch_block_create(0, ^{NSLog(@"previousBlock begin");[NSThread sleepForTimeInterval:1];NSLog(@"previousBlock done");});dispatch_async(queue, previousBlock);dispatch_block_t notifyBlock = dispatch_block_create(0, ^{NSLog(@"notifyBlock");});//当previousBlock执行完毕后,提交notifyBlock到global queue中执行dispatch_block_notify(previousBlock, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), notifyBlock);

运行结果:

GCDTests[17129:895673] previousBlock begin
GCDTests[17129:895673] previousBlock done
GCDTests[17129:895673] notifyBlock


  • 4、dispatch_group_wait
    dispatch_group_wait会同步地等待group中所有的block执行完毕后才继续执行,类似于dispatch barrier

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
//将任务异步地添加到group中去执行
dispatch_group_async(group,queue,^{ NSLog(@"block1"); });
dispatch_group_async(group,queue,^{ NSLog(@"block2"); });
dispatch_group_wait(group,DISPATCH_TIME_FOREVER);
NSLog(@"go on");

执行结果如下,只有block1跟block2执行完毕后才会执行dispatch_group_wait后面的内容。

GCDTests[954:41031] block2
GCDTests[954:41032] block1
GCDTests[954:40847] go on


  • 5、dispatch_group_notify
    功能与dispatch_group_wait类似,不过该过程是异步的,不会阻塞该线程,dispatch_group_notify有三个参数

void dispatch_group_notify(dispatch_group_t group, //要观察的groupdispatch_queue_t queue, //block执行的队列dispatch_block_t block); //当group中所有任务执行完毕之后要执行的block

简单的示意用法:

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group,queue,^{ NSLog(@"block1"); });
dispatch_group_async(group,queue,^{ NSLog(@"block2"); });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{NSLog(@"done");
});
NSLog(@"go on");

可以看到如下的执行结果

GCDTests[1046:45104] go on
GCDTests[1046:45153] block1
GCDTests[1046:45152] block2
GCDTests[1046:45104] done



推荐阅读
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
    Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ... [详细]
  • 深入解析Java多线程与并发库的应用:空中网实习生面试题详解
    本文详细探讨了Java多线程与并发库的高级应用,结合空中网在挑选实习生时的面试题目,深入分析了相关技术要点和实现细节。文章通过具体的代码示例展示了如何使用Semaphore和SynchronousQueue来管理线程同步和任务调度。 ... [详细]
  • 优化Flask应用的并发处理:解决Mysql连接过多问题
    本文探讨了在Flask应用中通过优化后端架构来应对高并发请求,特别是针对Mysql 'too many connections' 错误的解决方案。我们将介绍如何利用Redis缓存、Gunicorn多进程和Celery异步任务队列来提升系统的性能和稳定性。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • 本文探讨了如何通过一系列技术手段提升Spring Boot项目的并发处理能力,解决生产环境中因慢请求导致的系统性能下降问题。 ... [详细]
  • 在现代Web应用中,当用户滚动到页面底部时,自动加载更多内容的功能变得越来越普遍。这种无刷新加载技术不仅提升了用户体验,还优化了页面性能。本文将探讨如何实现这一功能,并介绍一些实际应用案例。 ... [详细]
  • 由二叉树到贪心算法
    二叉树很重要树是数据结构中的重中之重,尤其以各类二叉树为学习的难点。单就面试而言,在 ... [详细]
  • Linux环境下进程间通信:深入解析信号机制
    本文详细探讨了Linux系统中信号的生命周期,从信号生成到处理函数执行完毕的全过程,并介绍了信号编程中的注意事项和常见应用实例。通过分析信号在进程中的注册、注销及处理过程,帮助读者理解如何高效利用信号进行进程间通信。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 本文详细介绍了Java中实现异步调用的多种方式,包括线程创建、Future接口、CompletableFuture类以及Spring框架的@Async注解。通过代码示例和深入解析,帮助读者理解并掌握这些技术。 ... [详细]
  • 深入解析Hadoop的核心组件与工作原理
    本文详细介绍了Hadoop的三大核心组件:分布式文件系统HDFS、资源管理器YARN和分布式计算框架MapReduce。通过分析这些组件的工作机制,帮助读者更好地理解Hadoop的架构及其在大数据处理中的应用。 ... [详细]
author-avatar
一枝红杏出墙来2001
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有