继续谈谈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

目录
相关文章
|
编解码 算法 数据可视化
源码解读 | 单目相机实现3D目标检测—CaDDN
源码解读 | 单目相机实现3D目标检测—CaDDN
575 0
|
8月前
|
人工智能 架构师 决策智能
agentUniverse X 浙大太乙平台,开源共建招募令来啦,3万奖金等你拿!
agentUniverse 首期开源共建活动正式上线啦!3万奖金池等大家贡献瓜分~
|
4月前
|
数据采集 机器学习/深度学习 自然语言处理
NLP助力非结构化文本抽取:实体关系提取实战
本文介绍了一套基于微博热帖的中文非结构化文本分析系统,通过爬虫代理采集数据,结合NLP技术实现实体识别、关系抽取及情感分析。核心技术包括爬虫模块、请求配置、页面采集和中文NLP处理,最终将数据结构化并保存为CSV文件或生成图谱。代码示例从基础正则规则到高级深度学习模型(如BERT-BiLSTM-CRF)逐步演进,适合初学者与进阶用户调试与扩展,展现了中文NLP在实际场景中的应用价值。
235 3
NLP助力非结构化文本抽取:实体关系提取实战
|
7月前
|
JSON 监控 API
唯品会商品详情接口(唯品会 API 系列)
唯品会商品详情接口助力电商发展,提供商品名称、价格、规格等详细信息,支持HTTP GET/POST请求,响应为JSON格式。开发者可通过API Key和商品ID获取数据,应用于电商数据分析、竞品调研、应用开发及价格监控,提升业务效率与竞争力。示例代码展示Python调用方法,方便快捷。
|
8月前
|
监控 安全 数据中心
基于Intel RDT平台技术的系统资源隔离能力提升|龙蜥大讲堂103期
龙蜥大讲堂103期探讨了基于Intel RDT平台技术在Koordinator项目NRI模式中提升系统资源隔离能力。课程分为三部分:1) NRI与Koordinator,介绍NRI框架及其应用;2) RDT与Koordinator,讲解RDT技术如何优化资源分配,提高集群效率;3) RDT技术发展,展望未来RDT技术的演进方向及在Koordinator中的集成进展。
152 0
|
机器学习/深度学习 数据采集 数据可视化
NumPy 正态分布与 Seaborn 可视化指南
该文档介绍了正态分布(高斯分布),包括它的简介、特征、生成正态分布数据的方法(使用 NumPy 的 `random.normal()` 函数)、如何用 Seaborn 可视化正态分布,以及正态分布的应用(如统计学、机器学习、金融和工程)。还提供了一些练习,如生成特定参数的正态分布随机数并绘图,以及比较不同标准差下的分布形状。最后,给出了练习的解决方案,展示了如何执行这些任务。
170 1
|
存储 自然语言处理 安全
DevEco Studio项目构建讲解、编写页面、布局介绍、页面跳转
DevEco Studio项目构建讲解、编写页面、布局介绍、页面跳转
1278 0
DevEco Studio项目构建讲解、编写页面、布局介绍、页面跳转
|
编解码 项目管理
Adobe Premiere2023最新版无须激活版绿色安装包
Adobe Premiere 就是你们很熟悉的PR,又更新啦!这次分享的是2023版本的PR,熟悉的小伙伴应该都清楚这款软件安装包大小就没超过2GB,但是这个版本它足足有8GB之大!单单从安装包上,就很明确的表示了,此次更新的庞大,具体更新详细内容大家可以去Adobe官网查看一下
1172 0
|
物联网 API 开发工具
Stm32 固件库介绍及获取方法 | 学习笔记
快速学习 Stm32 固件库介绍及获取方法
Stm32 固件库介绍及获取方法 | 学习笔记
|
机器学习/深度学习 编解码 人工智能
21秒看尽ImageNet屠榜模型,60+模型架构同台献艺
60+模型架构,历年十几个 SOTA 模型,这 21 秒带你纵览图像识别的演进历史。
757 0
21秒看尽ImageNet屠榜模型,60+模型架构同台献艺

热门文章

最新文章