浅谈一下Sanic和Nodejs事件循环的区别

浅谈一下Sanic和Nodejs事件循环的区别

最近做了几个python的sanic项目发现sanic的事件循环有些无法理解的问题,钻研了一下。

二者事件循环的主要区别

Sanic 是基于 Python 异步框架,而 Node.js 是以 JavaScript 为编程语言并内置了异步事件驱动的架构。它们都采用了事件循环来处理异步操作,但实现机制和相关概念不尽相同。

Node.js 事件循环:

  • Node.js 中的事件循环由 libuv 库提供,处理异步I/O操作。
  • JavaScript 是单线程语言,在 Node.js 中通过事件循环来实现非阻塞I/O。
  • 所有的异步任务都会被放入事件队列中,在主线程之外执行。
  • 当异步操作执行完毕后,它们的回调函数会被加入到一个特定的队列,称为事件队列。
  • 事件循环负责从事件队列中取出消息并执行对应的回调。
  • Node.js 的 async/await 是基于 Promises 实现的,可以使异步代码看起来像同步代码。

Sanic 事件循环:

  • Sanic 是建立在 Python 的 asyncio 库之上的,利用 Python 的原生协程(coroutines)和 async/await 语法来进行异步非阻塞编程。
  • Python 的 asyncio 提供了自己的事件循环实现,用来调度协程的执行。
  • 在 Sanic 中,异步请求处理函数通常以 async 关键字开头,表示它们是一个协程。
  • 当你在 Sanic 的异步函数中使用同步代码(比如常规的阻塞 I/O 操作)时,它会阻塞整个事件循环,因为它的事件循环在等待这个操作完成。
  • 为了进行异步I/O操作,你通常会使用提供了异步接口的库(如 asyncpg 直接访问 PostgreSQL,aiohttp 发送 HTTP 请求等)。

如果在 Sanic 中遇到代码阻塞问题,可能的原因如下:

  1. 你可能在异步函数中使用了阻塞的I/O调用或者长时间运行的代码,这会占据事件循环并导致其他操作无法即时处理。
  2. 应该使用异步兼容的库来执行I/O操作,如果你试图使用同步的库,就算是在异步函数中,也会造成阻塞。

例如,需要使用异步数据库库来进行数据库操作,使用 aiohttp 来执行HTTP请求,而不是使用 requests 这种同步的库。

一种常见的错误模式是在异步处理程序中不加区分地使用同步代码,这会导致整个服务性能下降。解决这个问题的关键是识别出哪些操作会阻塞事件循环,并将这些操作转换为非阻塞的异步调用。此外,你可能需要熟悉 Python 中的 asyncio.sleep() 替代 time.sleep(),以及其他类似的异步替代函数和模式来避免不小心插入阻塞代码。

为什么node中可以相对随意的使用I/O操作,而sanic就要避免使用阻塞I/O

Node.js 和 Sanic (基于 Python 的 asyncio) 都是异步框架,但是它们处理异步操作的方法不同。这些差异导致了在使用 I/O 操作时需要采用不同的考虑方式。

在 Node.js 中:

  • Node.js 的设计是单线程的,它利用 JavaScript 事件循环来执行异步操作。所有的 I/O 操作在 Node.js 中被设计为非阻塞,这是 Node.js 的核心优势之一。
  • 当 I/O 操作被执行时,它们会被委托给底层的系统内核,而 JavaScript 事件循环会继续执行其他任务。
  • 当 I/O 操作完成时,回调函数将会被放进事件队列中,并在事件循环可以处理它们的时候被调用。
  • 这样做的结果是,开发者可以较为自由地在 Node.js 中执行 I/O 操作而无需担心阻塞整个应用,因为所有的 I/O 默认就是异步且非阻塞的。

在 Sanic 和 asyncio 中:

  • asyncio 需要明确地将事情声明为异步。如果在协程中使用同步代码或者库,那么它会阻塞正在运行的协程,从而阻塞整个事件循环。
  • 这就意味着在 Sanic(或任何基于 asyncio 的框架)中,你需要确保所有的 I/O 操作都是通过使用 asyncawait 关键字,以及利用可以异步执行 I/O 操作的库(例如 aiohttp 替代 requestsaiomysql 替代 PyMySQL 等)。
  • 如果在异步函数中执行阻塞的 I/O 或者长时间执行的同步代码,它会暂停事件循环,阻塞事件循环上的其他协程,直到该操作完成。这会造成整个应用性能的下降,因为其他的并发请求无法被及时处理。

总结来说,Node.js 让所有的 I/O 操作变得默认非阻塞,并通过事件驱动的模型简化了异步编程模式。而在 Sanic/asyncio 中,由于 Python 是多线程语言,所以需要开发者显式地使用异步 I/O 来获得相同的非阻塞行为。这是为什么在 Sanic 中要避免使用阻塞 I/O,而在 Node.js 中可以相对自由使用 I/O 操作的主要原因。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值