python twisted是什么_Twisted基础介绍(一)
什么是Twisted
1.Twisted是一个基于Reactor模式的异步IO网络框架
首先说下什么是Reactor模式。Reactor模式就是利用循环体来等待事件发生,然后处理发生的事件的模式,如上图所示。
Reactor主要有如下两个功能:监视一系列与你I/O操作相关的文件描述符(description)。监视文件描述符的过程是异步的,也就是说整个循环体是非阻塞的;
不停地向你汇报那些准备好的I/O操作的文件描述符。
Twisted就是基于Reactor模式帮我们抽象出了异步编程模型以及各种非阻塞的io模块(tcp、http、ftp等),使我们很方便地进行异步编程。
2.Twisted程序我们将Twisted程序分为两个部分:我们写的代码和Twisted代码;
我们的代码与Twisted代码运行在同一个线程中;
当我们的代码运行时,Twisted代码是处于暂停状态的;
同样,当Twisted代码处于运行状态时,我们的代码处于暂停状态;
Reactor事件循环会在我们的回调函数返回后恢复运行。
在一个回调函数执行过程中,实际上Twisted的循环是被有效地阻塞在我们的代码上的。因此,我们应该确保回调函数不要浪费时间(尽快返回)。特别需要强调的是,我们应该尽量避免在回调函数中使用会阻塞I/O的函数。否则,我们将失去所有使用reactor所带来的优势。Twisted是不会采取特殊的预防措施来防止我们使用可阻塞的代码的,这需要我们自己来确保上面的情况不会发生。正如我们实际看到的一样,对于普通网络I/O的例子,由于我们让Twisted替我们完成了异步通信,因此我们无需担心上面的事情发生。
3.Twisted中的ReactorTwisted的Reactor只有通过调用reactor.run()才启动;
reactor循环是在其开始的线程中运行,也就是运行在主线程中;
一旦启动,reactor就会在程序的控制下(或者具体在一个启动它的线程的控制下)一直运行下去;
reactor空转时并不会消耗任何CPU的资源;
并不需要显式的创建reactor,只需要引入就OK了。
到这里是不是还感觉云里雾里的,不要紧,下面通过几个例子来更好的理解Twisted。
Twisted编程模型
1.阻塞和非阻塞客户端对比
开启诗歌服务器(开两个服务端口):
$ cd twisted-intro
$ python blocking-server/slowpoetry.py --port 10001 poetry/ecstasy.txt --num-bytes 300
$ python blocking-server/slowpoetry.py --port 10002 poetry/ecstasy.txt --num-bytes 300
使用阻塞版本客户端从两个服务端口下载诗歌:
$ python blocking-client/get-poetry.py 10001 10002
Task 1: get poetry from: 127.0.0.1:10001
Task 1: got 3083 bytes of poetry from 127.0.0.1:10001 in 0:00:07.710390
Task 2: get poetry from: 127.0.0.1:10002
Task 2: got 3083 bytes of poetry from 127.0.0.1:10002 in 0:00:07.710416
Got 2 poems in 0:00:15.420806
阻塞版本中Task 2得等到Task 1结束之后才能进行,总耗时15.4s。
使用twisted编写的异步版本客户端从两个服务端口下载诗歌:
$ python twisted-client-1/get-poetry.py 10001 10002
Task 1: got 300 bytes of poetry from 127.0.0.1:10001
Task 2: got 300 bytes of poetry from 127.0.0.1:10002
Task 1: got 300 bytes of poetry from 127.0.0.1:10001
Task 2: got 300 bytes of poetry from 127.0.0.1:10002
Task 1: got 300 bytes of poetry from 127.0.0.1:10001
Task 2: got 300 bytes of poetry from 127.0.0.1:10002
Task 1: got 300 bytes of poetry from 127.0.0.1:10001
Task 2: got 300 bytes of poetry from 127.0.0.1:10002
Task 1: got 300 bytes of poetry from 127.0.0.1:10001
Task 2: got 300 bytes of poetry from 127.0.0.1:10002
Task 1: got 300 bytes of poetry from 127.0.0.1:10001
Task 2: got 300 bytes of poetry from 127.0.0.1:10002
Task 1: got 300 bytes of poetry from 127.0.0.1:10001
Task 2: got 300 bytes of poetry from 127.0.0.1:10002
Task 1: got 300 bytes of poetry from 127.0.0.1:10001
Task 2: got 300 bytes of poetry from 127.0.0.1:10002
Task 1: got 300 bytes of poetry from 127.0.0.1:10001
Task 2: got 300 bytes of poetry from 127.0.0.1:10002
Task 1: got 300 bytes of poetry from 127.0.0.1:10001
Task 2: got 300 bytes of poetry from 127.0.0.1:10002
Task 1: got 83 bytes of poetry from 127.0.0.1:10001
Task 2: got 83 bytes of poetry from 127.0.0.1:10002
Task 1 finished
Task 2 finished
Task 1: 3083 bytes of poetry
Task 2: 3083 bytes of poetry
Got 2 poems in 0:00:07.810432
twisted编写的异步版本中Task 1和Task 2是交替运行的,总耗时7.8s。
可以看到Twisted异步版本客户端比阻塞版本高效很多,原因是异步版本的io操作是非阻塞式的,遇到io等待时会先去处理其他任务。
2.Twisted低层接口编写的诗歌下载客户端程序
示例代码:twisted-intro/twisted-client-1/get-poetry.py
关键代码:reactor.addReader(reader):添加一个读取器;
需要实现一个reader,reader是一个读取器,需要遵守Twisted.internet.interfaces的IReadDescriptor接口规范,实现doRead、connectionLost、fileno三个方法;
doRead就是一个回调函数,当有socket准备就绪时被激活;
每当回调被激活,就轮到我们的代码将所有能够读的数据读回来然后非阻塞式的停止,如下图所示:
这种方式我们需要实现比较多的代码,比如需要实现底层socket通信(非阻塞)等。
3.Twisted高层接口编写的诗歌下载客户端程序
示例代码:twisted-intro/twisted-client-2/get-poetry.py
我们首先来看几个重要的类。
Transport:一个Twisted的Transport代表一个可以收发字节的单条连接。
Protocol:Twisted的Protocol抽象由interfaces模块中的IProtocol定义。Protocol定义了数据传输的协议,如TCP、FTP、IMAP或其他我们自己制定的协议;
Protocol实例如何得知它为哪条连接服务呢?如果你阅读IProtocol定义会发现一个makeConnection函数。这是一个回调函数,Twisted会在调用它时传递给其一个也是仅有的一个参数,即Transport实例。这个Transport实例就代表Protocol将要使用的连接。
Protocol Factory:一个连接对应一个Protocol实例,Protocol Factory会为每一个连接创建一个Protocol实例;
Protocol Factory的API由IProtocolFactory来定义,同样在interfaces模块中。Protocol Factory就是Factory模式的一个具体实现。buildProtocol方法在每次被调用时返回一个新Protocol实例,它就是Twisted用来为新连接创建新Protocol实例的方法;
在Protocol Factory中还可以定义回调函数,在某个事件发生时调用。
几个类的关系图如下:
再来看看get-poetry.py的程序逻辑:首先调用reactor的connectTCP方法,将服务器的ip、port以及Protocol Factory对象传入该方法;
然后Twisted会调用Protocol Factory实例的buidProtocol方法创建Protocol实例,并使Protocol和Factory关联,逻辑图如下:Twisted调用Protocol实例的makeConnection与transport联系起来:Protocol调用dataReceived回调接收Transport传过来的数据。
Twisted高层接口帮我们屏蔽了很多底层的实现,让我们更多的关注业务逻辑。实际的dataReceived回调过程应该是这样:
4.更加抽象的运用Twisted
示例代码: twisted-intro/twisted-client-3/get-poetry.py
此示例和twisted-client-2/get-poetry.py版本的代码不同就是从Protocol factory中把回调函数抽象出来,使Protocol Factory代码可以被复用:
# coding:utf-8
# 示例:异步从诗歌服务器下载诗歌
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, ClientFactory
class PoetryProtocol(Protocol):
"""定义数据传输协议"""
poem = ''
def dataReceived(self, data): # 接收数据
self.poem += data
def connectionLost(self, reason): # 当断开连接时执行
self.poemReceived(self.poem)
def poemReceived(self, poem):
self.factory.poem_finished(poem) # f执行factory类的poem_finished方法
class PoetryClientFactory(ClientFactory): # ClientFactory的buildProtocol方法,会实例化protocol类
"""1.指定protocol类,既告诉twisted用什么样的规则处理TCP数据流2.定义用户的回调和错误回调"""
protocol = PoetryProtocol # 指定protocol类
def __init__(self, callback, errback):
self.callback = callback
self.errback = errback
def poem_finished(self, poem):
self.callback(poem)
def clientConnectionFailed(self, connector, reason): # 当连接失败时调用错误回调
self.errback(reason)
def got_poem(poem): # 回调
poems.append(poem)
poem_done()
def poem_failed(err): # 错误回调
print >>sys.stderr, 'Poem failed:', err
errors.append(err)
poem_done()
def poem_done():
if len(poems) + len(errors) == len(addresses):
reactor.stop()
poems = []
errors = []
factory = PoetryClientFactory(got_poem, poem_failed)
reactor.connectTCP(host, port, factory)
reactor.run() # 启动事件循环
for poem in poems:
print(poem)
程序运行过程如下图所示:
总结:编写Twisted程序时,脑海中一定要有一个循环体,且将循环体分成两部分:我们的代码和Twisted代码;
Twisted代码:有各种写好的非阻塞网络模块,循环监听返回内容,一旦收到返回内容则调用回调函数,执行我们的业务逻辑;
我们的代码:各种回调函数,处理socket数据流;
整个循环体是单线程的,所以我们写的回调一定要是非阻塞的,否则就失去了异步的优势了。如果回调函数有io操作,那么需要将此回调异步化,下一篇内容会讲到。
python twisted是什么_Twisted基础介绍(一)相关推荐
- python exceptions怎么用_Python基础介绍 | Exceptions异常
想到本科时候学的Java,各种思想思路,但就是实践得少了,所以讲了也生疏,但让自己静静地敲一敲,你也就明白程序语言里没啥新鲜事. 今天来讲讲程序中的异常: 出现问题时会引发异常.例如,如果你尝试除以零 ...
- python twisted教程_twisted基础教程.pdf
twisted基础教程 Twisted 网络编程必备(一) 0.1 为什么使用Twisted? 如果你并不准备使用Twisted,你可能有很多异议.为什么使用Twisted 而不是其他网络函数 库或框 ...
- Python Twisted 介绍
Python Twisted介绍:http://blog.csdn.net/hanhuili/article/details/9389433 原文链接:http://www.aosabook.org/ ...
- Python Twisted介绍
原文链接:http://www.aosabook.org/en/twisted.html 作者:Jessica McKellar Twisted是用Python实现的基于事件驱动的网络引擎框架.Twi ...
- Python基础介绍
本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语 ...
- python介绍和用途-Python基础介绍(一)
Python基础介绍(一) 1. python是什么编程语言 编译型与解释型 编译器吧源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以极其语言来运行此程序,速度很快 ...
- 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍 一、pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主
利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍 一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目 ...
- python最基本的规则是什么_Python基础介绍(一)
Python基础介绍(一) 1. python是什么编程语言 编译型与解释型 编译器吧源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以极其语言来运行此程序,速度很快 ...
- python表单提交的两种方式_Flask框架学习笔记之表单基础介绍与表单提交方式
本文实例讲述了Flask框架学习笔记之表单基础介绍与表单提交方式.分享给大家供大家参考,具体如下: 表单介绍 表单是HTML页面中负责数据采集功能的部件.由表单标签,表单域和表单按钮组成.通过表单,将 ...
最新文章
- vim 初学简单设置
- python【力扣LeetCode算法题库】104-二叉树的最大深度
- Google Drive的linux客户端使用(还没弄完)
- 用imageMagick的composite合并图片
- 基于 Docker 打造前端持续集成开发环境
- 修改小程序swiper 点的样式_高质量的微信小程序样式模板应该长什么样?
- 在Microsoft System Center中利用您的现有投资管理VMware--Veeam MP v6.5
- 【java】java 扩展可回调的Future
- 服务器虚拟化平台 可信云认证,100%满足规范,华为云Stack首批通过可信云虚拟化云平台最高等级认证...
- js复制操作,复制成功弹出提示框
- 计算机辅助设计与制造实例教程答案,计算机辅助设计实例教程= Example Course of Computer Aided Design...
- 颜色代码查询,在线颜色选择器,RGB颜色对照表
- Java-如何防范CSRF攻击
- CleanMyMac X 4.8版本更新!
- Deep Learning Algorithm for Cyberbullying Detection
- PicoNeo3开发VR项目
- linux离线安装jemalloc,jemalloc在linux上从安装到使用
- EXT.JS 学习笔记
- Android iText向pdf模板插入数据和图片
- 免费java视频教程大全在线观看