异步编程如何在单线程编程模型中工作?

Posted

技术标签:

【中文标题】异步编程如何在单线程编程模型中工作?【英文标题】:How does Asynchronous programming work in a single threaded programming model? 【发布时间】:2012-02-17 10:38:22 【问题描述】:

我在浏览node.js的细节时才知道,它支持异步编程,尽管它本质上提供了一个单线程模型。

在这种情况下如何处理异步编程?是不是就像runtime自己创建和管理线程,但是程序员不能显式创建线程?如果有人能指出一些资源来了解这一点,那就太好了。

【问题讨论】:

【参考方案1】:

Ryan 说得最好:同步/异步与单/多线程正交。对于单线程和多线程情况,有一个主事件循环使用Reactor Pattern 调用注册的回调。对于单线程情况,回调在主线程上按顺序调用。对于多线程情况,它们在单独的线程上调用(通常使用线程池)。这实际上是一个有多少争用的问题:如果所有请求都需要同步访问单个数据结构(例如订阅者列表),那么拥有多线程的好处可能会减少。这取决于问题。

就实现而言,如果框架是单线程的,那么它很可能使用poll/select 系统调用,即操作系统正在触发异步事件。

【讨论】:

【参考方案2】:

现在跟我说吧:异步编程并不一定意味着多线程。

javascript 是单线程运行时 - 您根本无法在 JS 中创建新线程,因为语言/运行时不支持它。

Frank 说得对(虽然很迟钝) 用英语:当事情进入您的应用程序时,有一个主事件循环来处理。因此,“处理这个 HTTP 请求”将被添加到事件队列中,然后在适当的时候由事件循环处理。

当您调用异步操作(例如 mysql 数据库查询)时,node.js 会向 mysql 发送“嘿,执行此查询”。由于这个查询需要一些时间(毫秒),node.js 使用 MySQL 异步库执行查询 - 回到事件循环并在等待 mysql 返回给我们的同时做 其他事情 .就像处理那个 HTTP 请求一样。

编辑:相比之下,node.js 可以简单地等待(什么都不做)让 mysql 回到它。这称为同步调用。想象一家餐厅,您的服务员将您的订单提交给厨师,然后在厨师做饭时坐下并转动他/她的拇指。在餐厅中,比如在 node.js 程序中,这种行为是愚蠢的——你有其他顾客饿了,需要被服务。因此,您希望尽可能异步,以确保一个服务员(或 node.js 进程)为尽可能多的人提供服务。

编辑完成

Node.js 使用 C 库与 mysql 通信,因此从技术上讲,这些 C 库可以产生线程,但在 Javascript 中,您不能对线程进行任何操作。

【讨论】:

更准确。 “Node.js 通过异步 API 与 mysql 通信。异步 API 的实现是用 C 语言实现的,该实现可能只是通过线程池运行同步 API”。异步 API 可能在内部使用线程池这一事实是您不关心的低级细节。 啊,所以mysql在不同的线程中运行,然后在完成后将事件添加回JS。如果我想制作自己的异步模块,我可以使用 node 中的子进程来达到相同的效果。 我认为这里最好避免使用“线程”这个词——人们听到它时会跳出错误的结论。异步调用可以使用线程,或者 fork 进程,或者做任何事情;重要的是,事件循环后面可能会发生回调或事件。 餐厅-服务员-厨师的例子真的很到位,+1。【参考方案3】:

重申服务员/厨师的类比:

你的程序是一个服务员(“你”),而 JavaScript 运行时是一个厨房,里面满是做你要求的事情的厨师。

服务员和厨房之间的接口由队列调解,因此请求不会在容量过剩的情况下丢失。

所以你的程序被分配了一个执行线程。您一次只能等一张桌子。每次您想卸载一些工作(例如制作食物/发出网络请求)时,您都会跑到厨房并将订单固定到板(队列)上,以便厨师(运行时)在他们有空闲容量时拿起.厨师会在订单准备好时通知您(他们会回电给您)。与此同时,你去等另一张桌子(你没有被厨房挡住)。

所以接受的答案具有误导性。 JavaScript 运行时定义为多线程,因为 I/O 不会阻塞您的 JavaScript 程序。作为服务员,您可以在厨房做饭的同时继续为顾客服务。这涉及至少两个执行线程。现实情况是,运行时将在幕后维护多个执行线程,以便有效地为与您的脚本直接对应的单个线程提供服务。

按照设计,只有一个执行线程被分配给 JavaScript 程序的同步运行。这是一件好事,因为它使您的程序比必须自己处理多个执行线程更容易推理。不用担心:您的 JavaScript 程序仍然会变得非常复杂!

【讨论】:

以上是关于异步编程如何在单线程编程模型中工作?的主要内容,如果未能解决你的问题,请参考以下文章

网络编程之异步IO,rabbitMQ笔记

低功耗设计的最佳编程模型:异步编程

思考!低功耗设计的最佳编程模型:异步编程

多线程之异步编程: 经典和最新的异步编程模型,async与await

JavaScript 编程模型及异步编程讲解

嵌入式软件异步编程:冥想