1

一段时间以来,我一直在使用各种并发构造,并没有过多考虑所有魔法是如何发生的,这最近让我越来越不安。

为了纠正这种……感觉,我一直在阅读异步是如何在幕后工作的。当我说异步时,在这种情况下,我指的是用户空间/绿色线程/协作多任务处理,尽管我假设其中一些概念也适用于传统的操作系统管理线程,因为涉及到调度程序和工作线程。

我看到一个工作人员如何暂停自己并让其他工作人员执行,但在非阻塞库代码的最低级别,调度程序如何知道先前暂停工作人员的工作何时完成并唤醒该工作人员?

  • 例如,如果您在某种异步块中启动工作人员并执行通常会阻塞的操作(例如 HTTP 请求、SQL 查询、其他 I/O),那么即使您的调用代码是异步的,该操作(库代码) 更好地使用您的异步框架,或者您已经有效地破坏了使用它的目的并阻止您的调度程序在等待您的阻塞调用时调用其他等待操作(您的函数是什么颜色问题),该调用在内部执行你的非阻塞调用代码,来完成。

  • 所以现在我们有异步代码调用其他异步库代码,现在我再次问自己这个问题 -异步库代码如何知道何时暂停和恢复操作?

对我来说,触发 HTTP 请求、继续前进并稍后返回以检查结果的想法很奇怪——不是从概念上而是从实现的角度来看。

您如何执行部分操作,例如发送 TCP 数据包,然后继续执行程序的其余部分,稍后再返回并检查结果是否已交付。送到什么地方?一个插座?

现在我们又深入了一层,您正在使用套接字选择来避免创建线程和阻塞,但是,再次......

  • 这些套接字如何开始操作,在完成之前继续前进,然后 select 如何知道数据何时可用?
  • 您是否不断检查一些缓冲区以查看字节是否已在无限循环中传递,如果没有则继续?

无论如何 - 我想你知道我要去哪里......

我主要关注 HTTP 作为一个激励性的例子,但是同样的问题也适用于任何正常的阻塞操作——它到底是如何工作的?

以下是我在研究该主题时发现的一些有用的资源,这些资源为这个问题提供了参考:

  • David Beazley 的精彩视频Build Your Own Async将引导您完成一个调度程序的简单实现,该调度程序通过在等待队列中休眠来触发回调并暂停执行。我发现这个视频非常有启发性,但它有点短,因为它向您展示了使用异步睡眠如何释放调度程序来执行其他工作人员,但并没有真正了解当您在那些工作人员中调用代码时会发生什么本身必须是非阻塞的,因此它与调度程序配合得很好。

  • 非阻塞 IO 如何在幕后工作- 这让我的理解更加深入,但仍然存在一些不确定性。

4

0 回答 0