tornado异步编程与node.js异步编程

news/2024/7/9 16:54:39 标签: python, c/c++, epoll

tornado是由FaceBook开源的一个异步python框架,node.js是由Joyent资助的开源项目,致力于提供一套编写高性能并发Web应用的JavaScript框架。这篇博客就简单谈一谈两种异步框架在Linux下的异同,如果有错误或者表达不恰当的地方欢迎各路大神指正。

在Linux下,node.js靠libev和libeio配合使用来实现异步I/O。libev是一个事件驱动库,基于poll/epoll提供的I/O复用方式,主要用于事件驱动的网络编程。libeio是异步版的POSIX API,主要负责文件I/O操作,他仅仅依赖于pthread,可以和libev配合使用。libev和libeio都是通过c和c++来实现的,所以node.js的底层是c和c++。

tornado的异步主要是通过 ioloop和iostream这2个模块来实现的。ioloop是tornado自己实现的事件驱动模型,和libev一样,也是对poll/epoll的封装,他使用_handlers保存(fd,handler)的映射关系,_events保存就绪的fd以及对应的events事件,tornado提供了add_handler, update_handler、remove_handler这3个方法对handler进行操作。然后调用start函数就可以开始对所有的fd进行轮询,并且调用对应的handler。而iostream是对ioloop的一层封装,主要实现socket的异步调用,主要由以下的3个方法实现读写操作read_until, read_bytes, write。

从异步的实现方式上面看,在Linux下2者底层都是对poll/epoll的封装,只是一个底层由c实现,另一个完全由python实现。

从代码风格上讲我觉得tornado比node.js有优势,node.js是函数式编程,异步操作处理得到的结果只能通过回调函数进行处理,假如说我们需要进行多级的函数调用,并且结果互相依赖,那么这个时候就只能在回调函数里面嵌套回调函数,这样的代码可读性和可维护性都不高,比如:

当我们需要读取一个文件的时候,我们会执行以下语句:

fs.readFile('/path', function (err, data) {
  if (err) throw err;
  console.log(data);
});

当我们需要读取一个文件的内容,并且根据这个文件的内容读写另外一个文件的时候,我们就需要执行以下语句:

fs.readFile('/path', function (err, data) {
  if (err) throw err;
  fs.readFile(data, function (err, data2) {
    if (err) throw err;
    // 在这里处理data2的数据
  });
});

这个地方我们就在回调里面嵌套了一层回调,这里仅仅是2层,假如回调嵌套层数很多的话代码就不容易读懂,看起来结构就很乱。

tornado为了解决这个问题提供了一种使用同步的方式编码,并且使用异步的方式执行的方法。解决方式就是使用python的yield关键字和gen模块。

gen模块可以把一个函数调用里面的回调函数的参数当成返回值赋给变量,如果有多个参数就返回一个tuple。但是这个并没有解决异步调用时间差的问题,如果直接使用这个方法的话得到的值是None,因为回调函数刚刚加入轮询队列,还没有被执行,这个时候gen就尝试读取参数并且返回,这个时候得到的就是None。这个时候就需要yield关键字,这个关键字可以把一个函数变成一个生成器,简单的来说就是调用一个带有yield关键字的函数的时候,函数会先顺序执行到yield这一句,然后函数被挂起,当这个函数再一次被执行的时候,函数会从yield这一句接着往下执行。如果yield和gen搭配使用的话,函数会先执行到yield这一句,然后把调用的函数加入轮询队列,然后函数被挂起,等待轮询里面的函数执行完毕返回的时候函数再次被调用,通过gen取出回调函数里面的参数并且赋值给变量,函数接着往下执行。例如:

如果不使用gen模块的话异步调用需要这样写:

class AsyncHandler(RequestHandler):
    @asynchronous
    def get(self):
        http_client = AsyncHTTPClient()
        http_client.fetch("http://example.com",
                          callback=self.on_fetch)

    def on_fetch(self, response):
        do_something_with_response(response)
        self.render("template.html")

on_fetch就是回调函数

如果使用gen模块代码可以这样写:

class GenAsyncHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        http_client = AsyncHTTPClient()
        response = yield http_client.fetch("http://example.com")
        do_something_with_response(response)
        self.render("template.html")

代码中使用了@gen.coroutine修饰器,并且通过yield关键字将异步的代码变成同步的写法。这样代码的逻辑就很符合大多数人的编程思维,大大增强了代码的可读性。

总的来说node.js和tornado都是不错的异步编程工具,对于高并发都有很强的处理能力,node.js更适合全栈式的前后端分离的开发,tornado则是一个轻量级的python框架,他的优势更多的是在对websocket和长连接的支持,知乎就是使用tornado开发的。


http://www.niftyadmin.cn/n/649527.html

相关文章

实分析royden第四版答案_中考物理电功率考点分析,收藏了!

想学好物理,一定要会深度思考,并且能够运用所学知识去分析实际问题。这次咱们就来探讨一个初中物理中比较难的实际问题:电功率的问题。小编乱入电功率定义:电流在1秒内所做的功叫电功率。意义:表示消耗电能的快慢。符号…

django 怎样获取自增id的_django怎样获得框架自动定义的自增id字段

慕莱坞7535251django自定义字段类型,实现非主键字段的自增# -*- encoding: utf-8 -*-from django.db.models.fields import Field, IntegerFieldfrom django.core import checks, exceptionsfrom django.utils.translation import ugettext_lazy as _class AutoIncreField(Fiel…

后缀为php但是bin文件,什么是bin文件,后缀名bin是什么文件

什么是bin文件什么是垃圾箱,Bin文件是二进制文件,它的使用取决于系统或应用程序。后缀为[]的文件。bin]仅表示它是二进制格式。比如,【。bin]经常被用作虚拟光盘文件的后缀,但这并不意味着所有[。文件是虚拟光盘文件。Bin二进制文…

matlab将图片转换成16进制数据_MNIST手写数字数据库MATLAB版

MNIST手写数字数据库原始下载地址:MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges​yann.lecun.com0.前言网上很多转换MNIST手写数字的程序,鲜有MATLAB能直接使用的数据库版本。1.MATLAB元胞数组数据格式两个文件&…

架设win2003r2下配置好iis6+php+mysql_WINDOWS SERVER 2003系统下IIS配置PHP环境(图示详解版)...

关于本教程声明:本配置教程仅作抛砖引玉,正式生产用还需要对服务器进行更加详细的安全设置以及各方面性能调整。欢迎转载,请注明出处:http://ideacm.com.cn/read.php?73操作系统:Windows.Server.2003.R2,Enterprise.E…

2015.05.28 工作任务与心得

工作任务:javascript和Jquery,为什么要使用Jquerybind事件mozilla和ie内核的区别解决程序中的Jquery问题,动态动画的宽度问题使用Jquery制作动态效果网页的美化工作心得:1. http://www.gbtags.com/gb/share/1389.htm 这个博主写的…

qnap安装Linux程序,威联通QTS独家绝技,被忽视的神器——Ubuntu Linux Station

前言我个人认为威联通的QTS系统里面有三大神器:Virtualization Station、Container Station和Ubuntu Linux Station。前两者用途比较明确,衍生出来的玩法和用法比较多,相关文章也丰富一些。而Ubuntu Linux Station在我的文章里面虽然有多次推…

三十二楼层选几层最好_10年买房经验,教你如何买到最便宜的楼层

买房选什么楼层最好?这个话题一直是人们争论的观点,买高层上下楼不方便,买低层又怕采光蚊虫问题,那怎么选才能买到既便宜又相对不是很差的房子呢?今天小编就给和大家聊聊这个话题。开发商楼层是怎么定价的?…