Twisted是一个事件驱动型的网络引擎。因为事件驱动编程模型在Twisted的设计哲学中占有重要的地位,所以这里有必要花点时间来回顾一下究竟事件驱动意味着什么。程序员
事件驱动编程是一种编程范式,这里程序的执行流由外部事件来决定。它的特色是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的处理。另外两种常见的编程范式是(单线程)同步以及多线程编程。编程
让咱们用例子来比较和对比一下单线程、多线程以及事件驱动编程模型。图21.1展现了随着时间的推移,这三种模式下程序所作的工做。这个程序有3个任务须要完成,每一个任务都在等待I/O操做时阻塞自身。阻塞在I/O操做上所花费的时间已经用灰色框标示出来了。安全
图21.1 线程模型服务器
在单线程同步模型中,任务按照顺序执行。若是某个任务由于I/O而阻塞,其余全部的任务都必须等待,直到它完成以后它们才能依次执行。这种明确的执行顺序和串行化处理的行为是很容易推断得出的。若是任务之间并无互相依赖的关系,但仍然须要互相等待的话这就使得程序没必要要的下降了运行速度。网络
在多线程版本中,这3个任务分别在独立的线程中执行。这些线程由操做系统来管理,在多处理器系统上能够并行处理,或者在单处理器系统上交错执行。这使得当某个线程阻塞在某个资源的同时其余线程得以继续执行。与完成相似功能的同步程序相比,这种方式更有效率,但程序员必须写代码来保护共享资源,防止其被多个线程同时访问。多线程程序更加难以推断,由于这类程序不得不经过线程同步机制如锁、可重入函数、线程局部存储或者其余机制来处理线程安全问题,若是实现不当就会致使出现微妙且使人痛不欲生的bug。多线程
在事件驱动版本的程序中,3个任务交错执行,但仍然在一个单独的线程控制中。当处理I/O或者其余昂贵的操做时,注册一个回调到事件循环中,而后当I/O操做完成时继续执行。回调描述了该如何处理某个事件。事件循环轮询全部的事件,当事件到来时将它们分配给等待处理事件的回调函数。这种方式让程序尽量的得以执行而不须要用到额外的线程。事件驱动型程序比多线程程序更容易推断出行为,由于程序员不须要关心线程安全问题。架构
当咱们面对以下的环境时,事件驱动模型一般是一个好的选择:异步
程序中有许多任务,并且…函数
任务之间高度独立(所以它们不须要互相通讯,或者等待彼此)并且…测试
在等待事件到来时,某些任务会阻塞。
当应用程序须要在任务间共享可变的数据时,这也是一个不错的选择,由于这里不须要采用同步处理。
网络应用程序一般都有上述这些特色,这使得它们可以很好的契合事件驱动编程模型。
Transports表明网络中两个通讯结点之间的链接。Transports负责描述链接的细节,好比链接是面向流式的仍是面向数据报的,流控以及可靠性。TCP、UDP和Unix套接字可做为transports的例子。它们被设计为“知足最小功能单元,同时具备最大程度的可复用性”,并且从协议实现中分离出来,这让许多协议能够采用相同类型的传输。Transports实现了ITransports接口,它包含以下的方法:
write 以非阻塞的方式按顺序依次将数据写到物理链接上 writeSequence 将一个字符串列表写到物理链接上 loseConnection 将全部挂起的数据写入,而后关闭链接 getPeer 取得链接中对端的地址信息 getHost 取得链接中本端的地址信息
将transports从协议中分离出来也使得对这两个层次的测试变得更加简单。能够经过简单地写入一个字符串来模拟传输,用这种方式来检查。
Protocols描述了如何以异步的方式处理网络中的事件。HTTP、DNS以及IMAP是应用层协议中的例子。Protocols实现了IProtocol接口,它包含以下的方法:
makeConnection 在transport对象和服务器之间创建一条链接 connectionMade 链接创建起来后调用 dataReceived 接收数据时调用 connectionLost 关闭链接时调用