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

GCD的一点疑惑与自解

GCD其实已经了解了很久了,在实际工程中也会经常用,但是其实很多实践都是浅尝辄止。最近又在回头看这块儿的内容,有一些知识点,

GCD 其实已经了解了很久了,在实际工程中也会经常用,但是其实很多实践都是浅尝辄止。

最近又在回头看这块儿的内容,有一些知识点,原来不甚明白的,现在有了新的认识,刚好也记录下。

GCD 是一套方案,GCD 本身管理了一组线程池,GCD 负责线程池中的线程创建销毁、并且这种能力是动态化的,即可以充分利用当前 CPU 的多核特性。 添加到 GCD 队列中的任务,会由 GCD 来决定运行在哪一个线程上。也就是说,GCD Queue 是一个抽象概念, task 是添加到 Queue 中不假,但是实际仍然是运行在线程上的。

GCD Concurrent Queue 并行队列

GCD 的队列中的 task 遵循 FIFO (First In First Out)原则,但是 task 完成的顺序是不可测的。

上面的这段描述,是在当时阅读官方文档的时候,产生了疑惑,我的想法是,既然 task 是按照先后添加到 Queue 中的顺序进行执行的,那为啥完成时间就不一定了呢?

现在明白了,task 的执行压根和 Queue 关系不大,GCD 只是按照添加顺序从 Queue 中一个个拿出 task,扔到线程上去执行。有的 task 一会就完成了,有的需要比较长的时间,当然这个完成顺序就不一定了。

现在想想,当时应该是想当然的认为 GCD 只有在完成上一个任务后才会开启下一个任务,跟串行队列混淆了,从而导致疑惑的。

GCD 串行队列

串行队列就是只有完成上一个 task ,才会进行下一个 task 的执行。 所以完成顺序与添加顺序是相同的。

Objc GCD 队列疑惑

上图是摘录自 Objc.cn 中关于 GCD 队列的一张图。 但是在阅读时,我有下面几点疑惑:

  • 为什么 Custom Queues 这一层的关系如此复杂。
  • 为什么 Serial Queue 既指向了 Serial Queue ,又能指向 Concurrent Queue。
  • 最上面一层中的 Serial Queue 和 倒数第二层中的 Queues 有什么关系。

GCD 公开有 5 个不同的队列:运行在主线程中的 main queue,3 个不同优先级的后台队列,以及一个优先级更低的后台队列(用于 I/O)。 另外,开发者可以创建自定义队列:串行或者并行队列。自定义队列非常强大,在自定义队列中被调度的所有 block 最终都将被放入到系统的全局队列中和线程池中。

Objc 原文如上描述。

细细品味,其意思是,GCD Queues 有 5 大钦定的 Queue。 开发者当然也可以自定义 Queue(使用 dispatch_queue_create 函数), 前面说过,Queue 是一个抽象概念,只是简单的保存 task 而已,最终 task 还是要在 GCD Thread Pool 中完成的。

目标队列 Target Queue

之前讲过,task 最终是要从 Queue 中放到线程池中执行的。 其实还有一种情况,就是 task 可以从一个 Queue 中放到另一个 Queue 中。 需要设置当前 Queue 的 TargetQueue。 了解了这个概念,就能很清楚的明白上面的图了。

为了更加清楚的阐述这张图的表达意图,可以从这几条线说起:

S1 -> Main Queue

MainQueue 这个队列中的 task 最终都会放到主线程上执行。如果所示,MainQueue 是指向 Main Thread。 也就是说,如果自定义队列时,如果这个自定义串行队列的 Target Queue 是 Main Queue,那么这些 task 将都会放在主线程执行。

S3 -> Default Priority Queue

这里的意思很简单,自定义队列的默认 Target Queue 就是 Default Priority Queue,这也就是 Objc 所解释的 在自定义队列中被调度的所有 block 最终都将被放入到系统的全局队列中和线程池中 。 在 S3 队列中的任务,会一个接着一个地放入到 Global Queue 中,然后被执行。在前一个 task 完成之后,才会继续下一个 task。

C2 -> Default Priority Queue

同上,不过这里,会一咕噜的将 C2 中的 task 往 Global Queue 中放,不用管上一个 task 是否完成。

S2 -> S3

Serial Queue 的 target queue 同样是 Serial Queue

C1 + S4 -> C2

C1 的 Concurrent Queue 的 target queue = Concurrent Queue 这个就比较高级了。 在这个模式下,S4 中的 task 串行,C1 中的 task 并行。 但是最终它们这些任务都放在一个并发队列中。

最后

以上是个人对于 GCD 的一些见解,如有描述不对,还请及时指正。

转:https://juejin.im/post/5a30f24751882503dc53b3ab



推荐阅读
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 深入解析CAS机制:全面替代传统锁的底层原理与应用
    本文深入探讨了CAS(Compare-and-Swap)机制,分析了其作为传统锁的替代方案在并发控制中的优势与原理。CAS通过原子操作确保数据的一致性,避免了传统锁带来的性能瓶颈和死锁问题。文章详细解析了CAS的工作机制,并结合实际应用场景,展示了其在高并发环境下的高效性和可靠性。 ... [详细]
  • 双指针法在链表问题中应用广泛,能够高效解决多种经典问题,如合并两个有序链表、合并多个有序链表、查找倒数第k个节点等。本文将详细介绍这些应用场景及其解决方案。 ... [详细]
  • 利用python爬取豆瓣电影Top250的相关信息,包括电影详情链接,图片链接,影片中文名,影片外国名,评分,评价数,概况,导演,主演,年份,地区,类别这12项内容,然后将爬取的信息写入Exce ... [详细]
  • 解决Only fullscreen opaque activities can request orientation错误的方法
    本文介绍了在使用PictureSelectorLight第三方框架时遇到的Only fullscreen opaque activities can request orientation错误,并提供了一种有效的解决方案。 ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 本文深入解析了JDK 8中HashMap的源代码,重点探讨了put方法的工作机制及其内部参数的设定原理。HashMap允许键和值为null,但键为null的情况只能出现一次,因为null键在内部通过索引0进行存储。文章详细分析了capacity(容量)、size(大小)、loadFactor(加载因子)以及红黑树转换阈值的设定原则,帮助读者更好地理解HashMap的高效实现和性能优化策略。 ... [详细]
  • 构建基础的字符串队列实现方法
    在探讨如何构建基础的字符串队列实现方法时,我们发现许多开发者在面对这一问题时常常感到困惑。实际上,队列的基本原理非常简单,即遵循先进先出的原则。然而,在具体实现过程中,需要注意的是Java语言中并没有指针的概念,因此需要通过嵌套类来模拟指针,进而构建链表结构。这种实现方式不仅能够有效地管理字符串数据,还能提升代码的可读性和维护性。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • Python多线程编程技巧与实战应用详解 ... [详细]
author-avatar
倒霉熊丶JO_205
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有