前言
也玩了蛮久的scrapy了,scrapy底层用到的twisted还是要学习一下的,了解原理能提高自己的技术水平的说
异步编程
如果在某程序的运行时,能根据已经执行的指令准确判断它接下来要进行哪个具体操作,那它是同步程序,反之则为异步程序。(无序与有序的区别)
大部分编程语言中对方法的调用是同步执行的。例如在线程执行体内,即线程的调用函数中,方法的调用就是同步执行的。如果方法需要很长的时间来完成,比方说从Internet加载数据的方法,调用者线程将被阻塞直到方法调用完成。如果不希望调用被阻塞,异步方法调用 它通过使用一种立即返回的异步的变量方法并提供额外的方法来支持接受完成通知以及完成等待 以优化改进长期运行的(同步)方法。
反应器模式 reactor pattern
反应器模式是一种为处理服务请求并发提交到一个或者多个服务处理程序的事件设计模式。当请求抵达后,服务处理程序使用解多路分配策略,然后同步地派发这些请求至相关的请求处理程序
看英文版意思可能更清楚点
The reactor design pattern "Design pattern (computer science)") is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers.
反应器模式一定至少有一个在一直循环处理传入事件的loop
![](https://img.haomeiwen.com/i1589341/2b5108bc3f17d6d4.png)
基本使用
原理上的东西在写的时候可能更好的理解,先写个简单的程序吧
from twisted.internet import reactor
reactor.run()
twisted 就是一个反应堆模式,reactor是事件循环,而这正是twisted的核心,从文档和一些资料中我们知道
1.Twisted的reactor只有通过调用reactor.run()来启动。
2.reactor循环是在其开始的进程中运行,上面的代码也就是运行在主进程中。
3.一旦启动,就会一直运行下去。reactor就会在程序的控制下(或者具体在一个启动它的线程的控制下)。
4.reactor循环并不会消耗任何CPU的资源。
5.并不需要显式的创建reactor,只需要引入就OK了。
最后一条需要解释清楚。在Twisted中,reactor是单例模式,即在一个程序中只能有一个reactor,并且只要你引入它就相应地创建一个。
接下来就可以跑一个twisted的hello world
from twisted.internet import reactor
def hello():
print("hello world")
reactor.callWhenRunning(hello)
reactor.run()
hello 方法就是我们说的回调方法了,reactor 不需要知道回调方法的细节,只需要知道是哪个回调方法
1.reactor模式是单线程的。
2.像Twisted这种交互式模型已经实现了reactor循环,意味无需我们亲自去实现它。
3.我们仍然需要框架来调用我们自己的代码来完成业务逻辑。
4.因为在单线程中运行,要想跑我们自己的代码,必须在reactor循>环中调用它们。
5.reactor事先并不知道调用我们代码的哪个函数
![](https://img.haomeiwen.com/i1589341/c9a8a27d157574d3.png)
接下来写一个定时关闭reactor的例子
from twisted.internet import reactor
def hello():
print("hello world")
def count(i):
print(i)
if i==5:
reactor.stop()
else:
reactor.callLater(1,count,i+1)
reactor.callWhenRunning(hello)
reactor.callWhenRunning(count,1)
reactor.run()
print("reactor down")
上面这个程序,会在5s后关闭reactor,代码里使用了callLater函数为Twisted注册了一个回调函数 ,api可以查看文档twisted ReactorBase文档
有一个很好的地方就是twisted 里面做好了错误异常处理,如果回调函数里面有exception,twisted会捕捉到了并输出日志(所以scrapy spider中parse response的方法里面有错,也只会输出错误堆栈,而不会让爬虫挂掉)
结语
下一篇计划写下 twisted 的defer
先大体看下
异步编程中,defer机制主要是用来管理callback函数,在twisted中,许多功能的实现都是采用的事件驱动机制,在异步编程中,错误处理机制和同步程序并不一样,异步程序会无视错误执行下去。在异步程序中处理错误显得十分重要。defer就是来可以帮助我们来管理我们的callback和errback函数。合理的安排defer在异步编程中显得十分重要。
网友评论