twisted reactor calllater实现
twisted reactor calllater实现
1. calllater实现代码
测试源码:
from twisted.internet import reactor
from twisted.internet import defer
def func_1():
print('calllater测试')
time.sleep(5)
print('calllater结束')
# error handle
def test_deferred_a():
#d = test_retrurn_deferred()
reactor.callLater(4, func_1)
reactor.callLater(15, reactor.stop)
reactor.run() if __name__ == '__main__':
test_deferred_a()
1.1. 第一步:调用calllater
reactor.callLater(3, d.callback, 8)
先找到calllater
# <twisted.internet.selectreactor.SelectReactor object at 0x000000CE3BFC72B0>
@implementer(IReactorCore, IReactorTime,
IReactorPluggableResolver,
IReactorPluggableNameResolver, _ISupportsExitSignalCapturing)
class ReactorBase(object):
"""
Default base class for Reactors.
"""
def callLater(self,
_seconds, _f, *args, **kw):
"""See
twisted.internet.interfaces.IReactorTime.callLater.
"""
assert callable(_f), "%s
is not callable" % _f
assert _seconds
>= 0, \
"%s
is not greater than or equal to 0 seconds" % (_seconds,)
tple = DelayedCall(self.seconds()
+ _seconds, _f, args, kw,
self._cancelCallLater,
self._moveCallLaterSooner,
seconds=self.seconds)
self._newTimedCalls.append(tple)
return tple
DelayedCall基本上可以把它当作一个中间类,用于保存一些信息。
结果就是向self._newTimedCalls添加一个定时调用
self._newTimedCalls.append(tple)
可以看一下它的具体内容
_newTimedCalls= <class 'list'>:
[<twisted.internet.base.DelayedCall object at 0x000000CE3C2EA668>]
1.2.
第二步
reactor.run()
跳过一些前置处理内容,直接到mainloop
def mainLoop(self):
while self._started:
try:
while self._started:
# Advance
simulation time in delayed event
# processors.
self.runUntilCurrent()
t2 = self.timeout()
t = self.running and t2
self.doIteration(t)
except:
log.msg("Unexpected
error in main loop.")
log.err()
else:
log.msg('Main loop
terminated.')
进入self.runUntilCurrent()
def runUntilCurrent(self):
"""
运行所有挂起的calls
Run all pending timed calls.
"""
if self.threadCallQueue:
# Keep track of how
many calls we actually make, as we're
# making them, in case another
call is added to the queue
# while we're in this loop.
count = 0
total = len(self.threadCallQueue)
for (f, a,
kw) in self.threadCallQueue:
try:
f(*a, **kw)
except:
log.err()
count += 1
if count ==
total:
break
del self.threadCallQueue[:count]
if self.threadCallQueue:
self.wakeUp()
# insert new delayed
calls now
self._insertNewDelayedCalls()
now = self.seconds()
while self._pendingTimedCalls and (self._pendingTimedCalls[0].time
<= now):
call = heappop(self._pendingTimedCalls)
if call.cancelled:
self._cancellations-=1
continue
if call.delayed_time
> 0:
call.activate_delay()
heappush(self._pendingTimedCalls,
call)
continue
try:
call.called = 1
call.func(*call.args,
**call.kw)
except:
log.deferr()
if hasattr(call, "creator"):
e = "\n"
e += " C:
previous exception occurred in " + \
"a DelayedCall
created here:\n"
e += "
C:"
e += "".join(call.creator).rstrip().replace("\n","\n C:")
e += "\n"
log.msg(e)
if (self._cancellations > 50 and
self._cancellations
> len(self._pendingTimedCalls) >> 1):
self._cancellations
= 0
self._pendingTimedCalls
= [x for x in self._pendingTimedCalls
if not x.cancelled]
heapify(self._pendingTimedCalls)
if self._justStopped:
self._justStopped
= False
self.fireSystemEvent("shutdown")
进入self._insertNewDelayedCalls()
def _insertNewDelayedCalls(self):
for call in self._newTimedCalls:
if call.cancelled:
self._cancellations-=1
else:
call.activate_delay()
heappush(self._pendingTimedCalls,
call)
self._newTimedCalls
= []
从self._newTimedCalls中获取DelayedCall()实例,放入self._pendingTimedCalls
在runUntilCurrent中会调用self._pendingTimedCallsk列表相关对象,也就是执行func_1.
2.
其它
2.1.
代码解析1
heappush(self._pendingTimedCalls,
call)
函数heappush源自heapq.py
def heappush(heap, item):
"""Push
item onto heap, maintaining the heap invariant."""
heap.append(item)
_siftdown(heap, 0, len(heap)-1)
简单点说,它会构建一个有序堆,默认最小堆。
在构建有序堆过程中肯定是要比较int类型了,但call是一个类。
这里要回顾python类的特殊方法了,已有文档,不赘述。
call是DelayedCall类的实例,查看相关代码。
def __le__(self, other):
"""
Implement C{<=} operator between
two L{DelayedCall} instances.
Comparison is based on the C{time}
attribute (unadjusted by the
delayed time).
"""
return self.time
<= other.time
def __lt__(self, other):
"""
Implement C{<} operator between
two L{DelayedCall} instances.
Comparison is based on the C{time}
attribute (unadjusted by the
delayed time).
"""
return self.time
< other.time
twisted reactor calllater实现的更多相关文章
- (三)认识twisted reactor
一.reactor是单线程模型,简单粗暴,也就是说网络IO和我们的业务逻辑一般是在一个线程里,其中网络IO通过event loop的方式去异步执行,效率也很高.看下官网的这幅图,比较清晰 twiste ...
- twisted reactor分析
调用reactor.run(),就会调用到mainloop函数,从而调用到select或epoll,监控fd的读写. posixbase.py: def listenTCP(self, port, f ...
- twisted reactor 实现源码解析
twisted reactor 实现源码解析 1. reactor源码解析 1.1. 案例分析代码: from twisted.internet import protocol fro ...
- twisted reactor执行流程
#reactorbase的主循环 def mainLoop(self): while self._started: try: while self._started: # Advance simula ...
- Python Twisted、Reactor
catalogue . Twisted理论基础 . 异步编程模式与Reactor . Twisted网络编程 . reactor进程管理编程 . Twisted并发连接 1. Twisted理论基础 ...
- 理解twisted中的reactor和deferred(二)
Deferred可以添加多个回调函数,每个回调函数的结果作为下一个回调函数的参数 代码实例(可在pycharm中运行,摘自 https://twistedmatrix.com/documents/cu ...
- 理解twisted中的reactor和deferred(一)
Deferred是一个延迟加载对象,这个概念类似于tornado future,是调用异步操作返回的一个对象,其中包括了操作成功后的回调处理,错误后的回调处理. 简单讲,当我们需要执行一个耗时操作,比 ...
- 笔记-twisted源码-import reactor解析
笔记-twisted源码-import reactor解析 1. twisted源码解析-1 twisted reactor实现原理: 第一步: from twisted.internet ...
- Python中reactor,factory,protocol
最为简单的情况下,除了了解清reactor的简单使用,你还要了解Protocol和Factory.它们最终都会由reactor的侦听建立和run来统一调度起来. 建立服务器的第一个要解决的问题就是服务 ...
随机推荐
- log设计网站,一站式一键设计log网站
log设计网站,一站式一键设计log网站 log设计网站,一键式一站式设计log网站 待办 https://www.wix.com/buildyourwebsite5/designlogo?utm_s ...
- mac VirtualBox虚拟机装CentOS,并配置网络,使其发布的静态网站能访问
1.下载VirtualBox(macOS版本) 下载地址:https://download.virtualbox.org/virtualbox/6.0.8/VirtualBox-6.0.8-13052 ...
- mvn + testng + allure 生成自动化测试报告
最近学了个新东西,使用java的testng测试框架做自动化测试.并且声称自动化报告. (1)创建maven工程 File-New-Other (2)创建testng类 当前import org.te ...
- 解决Macbook Pro蓝牙不可用问题
谷歌搜索了下,在威锋网看到一个帖子,需要关机重置电源管理单元和系统NVRAM恢复出厂设置,具体操作如下:1.关机2.同时按下shift+control+option+power,保持5秒左右3.先按下 ...
- 理解javaBean
1:什么是JavaBean 组件?使用JavaBean 组件有什么优点?答案:现在软件开发都已经转向了基于组件的开发,目前具备代表性的组件技术有微软的COM.COM+,有Sun 的JavaBean 和 ...
- SparkSQL个人记录
SparkSQL将RDD封装成一个DataFrame对象,这个对象类似于关系型数据库中的表. 一.SparkSQL入门 1.创建DataFrame 相当于数据库中的一张表,它是一个只读的表,不能在运算 ...
- FreeRTOS学习笔记2:列表
list.h 列表结构List_t 列表:主要看三个 xLIST:1.5检查列表完整性的.但是需要开启.默认不开启 2:记录列表中列表项的 数量:3:记录当前列表项 索引号:4:列表中的最后一个 列表 ...
- 第二十三篇 玩转数据结构——栈(Stack)
1.. 栈的特点: 栈也是一种线性结构: 相比数组,栈所对应的操作是数组的子集: 栈只能从一端添加元素,也只能从这一端取出元素,这一端通常称之为"栈顶": 向栈中添加元 ...
- XSS 1
首先打开链接https://xss.haozi.me/ 点击打开第一题 然后看一下代码 尝试一下用简单的代码 可不可以通过 例如:<script>alert(1)</script& ...
- Linux - seq
1. 概述 生成序列的命令 之前貌似写过 seq 命令, 这次单独拉出来再写一次吧 节操先放一放 2. 命令 1. 帮助 命令 # 输出我就不打了, # 这个命令可用, 证明组件可用 > seq ...