继续谈谈Twisted

那我就来继续随便谈谈Twisted

首先讨论一下, 为什么需要twisted, 需要异步

为了更高效的利用CPU和资源, 提高用户的相应速度

任务需要较长时间才能完成分成两种情况,

1) 计算量较大, 需要CPU算好久才能算出来, 自然算出来才能给结果, 称为CPU等待.

2) 需要等待其他的数据, 比如需要从服务器等待获取信息, 需要从数据库等待查询结果, 这种虽然自己很闲, 无事可做, 但不得不干等, 称为I/O等待.

CPU等待是没办法的, 就是要算那么长时间, 唯一能做的是为了让用户体验好些, 大家轮流占用CPU, 这种典型的方法就是多线程...

I/O等待是应该需要优化的, 这是干等白白浪费并占住了资源, 使得其他用户也无法使用. 这儿就需要异步, 需要twisted, 需要callback.

本来我要等待数据, 然后程序才能继续, 异步的做法是, 把后续的处理程序封装成callback, errback, 把等待数据ready封装成event (让系统调用select去侦听数据I/O). 这样主程序不需要去专门等待某一个event, 有event触发就处理, 这就达到异步的效果.

 

所以在判断是否需要使用异步, 该不该使用twisted时, 只需要考虑是否存在I/O等待, 只要有I/O等待就应该考虑使用异步.

而Twisted的代码无论多么复杂, 其实都是在做如下这样简单的事情,

通过定义Protocal和Factory来解析请求

通过定义Callback来处理请求

定义I/O connection (将Factory作为参数, 包含Protocal和Callback), 并加到event loop(Reactor)中去

Run Reactor

 

再来, Twisted主要应用于什么场景, 使用Twisted真的比直接使用socket方便合理吗

Twisted主要用于开发server, 它就是为此而生的

下面我们通过简单的例子来和socket对比一下,

下面我们先来看一下客户端, 建立一个链接, 发送多条message

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))

    sock.send('Hello World1')
    time.sleep(3)
    sock.send('Hello World2')
    time.sleep(3)
    sock.send('Hello World3')

    sock.close()

 

先来看看socket的server, 显然这段代码只能接收到第一条message

如果需要接受所有的message, 必须在conn.recv前加上while, 这样保证接收到所有message后才去accept新的connection.

如果同时打开多个client, 那么这儿必须先接收完第一个client的所有message, 才能开始接收第二个client的...

这样就block了, 用户就不爽了...

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('localhost', 3000))
    sock.listen(5)
    while True:
        conn, addr = sock.accept()
        buf = conn.recv(1024)
        print 'Recv data:' + buf + '\n'

 

再来看看用Twisted实现的server, 可以试试同时打开多个上面的client, 该server是可以同时并发接收每个client的数据的, 而不是需要处理完一个client, 才开始处理下一个. 所以确实用Twisted开发server比直接使用socket方便合理许多.

from twisted.internet import protocol, reactor
from twisted.internet.protocol import Factory

class Echo(protocol.Protocol):

    def connectionMade(self):
        self.factory.numProtocols = self.factory.numProtocols+1
        print 'connectionMade'
        print 'numProtocols:'+ str(self.factory.numProtocols)

    def connectionLost(self, reason):
        self.factory.numProtocols = self.factory.numProtocols-1
        print 'connectionLost'
        print 'numProtocols:'+ str(self.factory.numProtocols)

    def dataReceived(self, data):
        #self.transport.write(data)
        print 'dataReceived:' + str(data)

myFactory = Factory()
myFactory.protocol = Echo
myFactory.numProtocols = 0

reactor.listenTCP(3000, myFactory)
reactor.run()

想想Twisted是怎么样实现这种异步的, 是怎么样保存各个connection并在之间自由切换的?

从头开始, 大家先简单把I/O想象成文件, 对于操作系统而言, I/O操作就等同于对文件的读写操作, 其他对系统是透明的.

对于一个Twisted server, 刚开始监听一个I/O端口(这儿可以想象对于Twisted有个侦听队列, 刚开始list中只有一个port), 等待请求...

请求到达(相当于conn, addr = sock.accept() ), 触发connectionMade Event, 并把该connection加到侦听队列.

某connection收到数据, 触发dataReceived Event

某connection closed, 触发connectionLost Event, 并把该connection从侦听队列中删除.

 

如果在某个callback, 如dataReceived中出现一个很耗时的任务时该怎么办, 比如需要从另外一个服务器获取数据.

异步中, callback使用的第一原则是, 不能block, 因为主线程一旦block, 啥事就都做不了

所以这儿必须要再次使用异步, 在callback中再次设置event和callback, 并将和远程服务器的connection加到侦听队列中.

本文章摘自博客园,原文发布日期:2011-11-12

时间: 2024-08-22 22:12:12

继续谈谈Twisted的相关文章

谈谈地方人才网站如何打造属于站点的特色“窗口”

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 一座城市的窗口能够展现自身形象,一个单位的窗口能够体现单位的优质服务,那么一个站点如果拥有自身特色的窗口又能够做什么呢?笔者在10年就建立了一个西安人才网站,网站运营到现在已经形成了以"免费"为基础的特色窗口,通过免费窗口的树立网站到现在已经形成了一定的规模,很多站长就要问我是如何打造自己的特色窗口的呢?下面笔者来详细谈谈

数学之美 系列二 -- 谈谈中文分词

谈谈中文分词----- 统计语言模型在中文处理中的一个应用 上回我们谈到利用统计语言模型进行语言处理,由于模型是建立在词的基础上的,对于中日韩等语言,首先需要进行分词.例如把句子 "中国航天官员应邀到美国与太空总署官员开会." 分成一串词:中国 / 航天 / 官员 / 应邀 / 到 / 美国 / 与 / 太空 / 总署 / 官员 / 开会. 最容易想到的,也是最简单的分词办法就是查字典.这种方法最早是由北京航天航空大学的梁南元教授提出的. 用 "查字典" 法,其实就

谈谈CMS内容管理系统的两种方案:XSL+XML和HTML (二)

xml 上篇讲到了XSL和XML如何在客户端浏览.也是CMS内容管理系统内容发布的一种形式,即XSL(模版)+XML(内容).     但是现实情况是由客户端浏览器不支持,这样做还会给服务器造成一定的负载,能够减轻服务器服务负载的最好方法就是完全实现静态页面的内容访问机制,当然这样就需要再次将XSL和XML生成HTML或者SHTML.     呵呵,这就是所说的CMS内容管理系统内容发布的第二种形式HTML或者SHTML.     在Java中有很多方式来实现,首先是先产生XSL文件,即模版文件

谈谈对网站页面的优化技巧

影响网站在搜索引擎结果里的表现有许多重要的因素!我们今天来谈谈网站的页面优化,页面优化包括下面几个因素:Title标题.URL.Meta Description元描述.代码结构.ALT属性的图像.网站内容. 一.页面标题(Title) 标题是网站页面优化中非常重要的因素.标题显示于浏览器上方,而且在搜索引擎的结果中显示在最上面的也是标题.标题是放关键词最好的地方,标题的写法要简洁.明了,而且每个页面的标题都不要一模一样.例如,我客户的网站首页标题是这样的:"专业净化工程,中央空调工程和机电安装工

谈谈SNS网站及网站会员分析

一直关注国内和国外SNS和社区的发展,运营过SNS两年,看过很多有关SNS方面的评论和分析,同时也一直在使用各个SNS网站,我想就从在SNS运营中碰到的一些问题和想法与各位交流一下,在这篇文章里我会提到一些具体的网站,如有不妥当的地方,欢迎大家给我提出指正和批评,我也将认真的回复您的意见,您的提出的任何东西都将对我极为有用,让我们共同提高! 先谈谈SNS的概念,以便于大家理解: Social Networking Service (简称SNS ,社会化网络软件)是Web 2.0 体系下的一个技术

谈谈网站的黏度

从事互联网行业10年,曾经负责过B2B网站的运营.创建过一家交友网站,参与运营过一家SNS网站,正好在这段休息的时间里,把自己在网站运营方面的一些心得.经验和问题总结出来,以期抛砖引玉与大家一起探讨. 网站运营范畴包括:产品设计.内容运营.内容更新.市场推广等相关的运营管理工作.具体表现为网站策划.产品开发.网络营销.客户服务.市场推广等: 那我就先从网站的黏度说起,作为一个网站运营者,我们不得不面临一个问题,就是如何提高网站会员的黏度,广义的黏度指的是用户对网站的重复使用度(依赖度.忠诚度),

谈谈JAVA程序的反编译

编译|程序   谈谈JAVA程序的反编译  如今JAVA语言在全世界范围正如火如荼般的流行,它广范地应用在INTERNET的数据库.多媒体.CGI.及动态网页的制作方面.1999年在美国对JAVA程序员的需求量首次超过C++! 最近分析一些JAVA程序,对JAVA的反编译进行了一番了解,下面将我所了解的情况作以下介绍,希望对JAVA爱好者有所帮助. JAVA是采用一种称做"字节编码"的程序结构,分为小程序(嵌入到HTML文件中)和应用程序(直接在命令状态下执行)两种类型.无论哪种结构,

谈谈网站运营需要注意的两个要素

按照网站发展的观点,"没有最好,只有更好",需要完善的细节会层出不穷,根本没有止境:网站也正是在这种无止境的追求中不断得到发展和提高的.   那么如何让网站的设计具有独特性和可用性?如何应用一些有效的方法来让自己的网站具有良好的用户体验?下面谈谈我的一些经验:   第一:体现网站的标识和定位 网站不能放过任何一个可能访问或者正在访问甚至访问过的用户,大家都削尖了脑袋想办法如何处理这三个问题.那么对于任何一个访问你网站的用户你就要了解他第一次打开你网站他关心什么.我个人觉得用户第一次打开

就SEO谈谈网站的宣传新策略

seo|策略 在做网站之前,相信很多站长都在为怎么把网站宣传出去而苦恼,一个做的再好的站点,如果没有宣传,在茫茫大海中想让别人发现你的网站,有点不现实.其流量无疑是很小的! 很多人都写过怎么宣传自己网站的方法,列举了很多方法,也许初看上去都很实际,也是很管用的方法,但是今天我想从另外一个方面来谈谈网站的宣传,注重于在搜索引擎上的体现,可能与之前的方法有些冲突,请各位在思考之后为自己的网站考虑好发展的路子! 首先想说下SEO.SEO是研究搜索引擎的一项技术,其致力于在不作弊的情况下,更好的整合网站