DispatchQueues 是如何在底层实现的?

How DispatchQueues are implemented under the hood?

我很好奇 DispatchQueue 到底是什么,我试图 google 此信息,但所有文档都相当抽象,没有提供有关实现的任何真实信息。在我的理解中,DispatchQueue 是某种存在于某处的实体,能够存储代码块,并由内核直接控制(通过嵌入到内核中的 GCD),它能够将这些块注入选定的(通过 GCD/Kernel) 线程。这是 DispatchQueue 的正确构想,还是我误解了什么?

你误解了,至少在某些地方是这样。 GCD 没有“融入内核”,它是一个运行在 POSIX 线程之上的库,这些线程是具有内核支持的 OS 级原语。 GCD 只是一组 API,使开发人员可以更轻松地在多个线程上工作,而无需自己管理线程。

不管怎样,您可以查看 GCD 的源代码。它在这里:https://opensource.apple.com/tarballs/libdispatch/ 也就是说,它充满了利用晦涩的编译器功能(分支预测指令和类似的东西)的微优化,而且它通常很难阅读和理解,即使对于有经验的系统程序员也是如此。

GCD 内部工作原理的完整详细解释超出了 Whosebug 答案的范围,但我会尝试编写一两段解释。

GCD 在幕后管理一定数量的 POSIX 线程,这些线程将用于以所需方式执行工作。它还维护许多数据结构来组织该工作,例如“队列”,可以将其视为“要完成的工作块列表”。还有一些组,可以让您在工作项列表完成时收到通知。还有各种 IO 机制允许异步 IO 为这些工作项提供服务。它可能(也可能不)使用各种内核服务(如线程、kqueue 等)来管理其部分工作负载,但这些服务并非特定于 GCD。

尽管如此,GCD 并没有什么“特别”或“幸运”的地方。事实上,GCD 有多个端口可以连接到各种其他操作系统,例如 Linux: http://nickhutchinson.github.io/libdispatch/ 的这个端口,这应该表明它不是 Darwin 内核特有的东西。换句话说,您可以从头开始编写自己的 GCD 版本,而无需重新编译内核。