最近在学习Twisted,在此归纳一些重要的概念和理念。
事件驱动编程(Event-Driven Programming)
Twisted是一个基于事件驱动的网络引擎。
在这种编程模式中,程序流程是由外部事件决定的。它的特性表现在一个事件循环以及采用回调来触发事件的相关动作。将此与其它两种常见模型进行比较应该会更益于理解,他们是单线程(同步)和多线程编程。
我们来看图说话。假如他们都需要处理三个任务,并且在进行I/O操作的时候均会发生阻塞。他们的表现形式将会如下图这样:
从左图可以看出,在单线程处理过程中,每个任务将会按顺序依次执行。当一个任务在处理I/O操作时,其它的任务都必须等待该I/O操作的完成。这无可避免的将会减慢整体的进度。
而在多线程处理中,得益于多个线程的协同工作,这一境况将大大改善,如中图所示。当一个线程发生I/O阻塞时,其它的线程并不会受其影响,这样就大大提高了效率。但同时,他也会带来一些问题。因为多个工作会同时进行,多数情况下多个线程间就不可避免的会共享数据,如果处理不得当就很容易引发各种问题。
最后一个就是右图所示的事件驱动版本,它会在一个线程中交错地处理多个任务。当执行I/O或一些较为费时的处理时,就会在事件循环中注册一个回调,使得它可以在完成这一费时的处理之后再被执行。回调的作用在于当完成这个事件触发之后应当如何进行处理。事件循环则会循环的检测事件的到来并将其正确的分派到对应的回调中去。这使得程序遭遇这种境况时能在无需其它线程的帮助下顺利的继续推进。
正因为此,使得事件驱动程序具有像多线程程序那样的并发性、又不失单线程中那样简单的逻辑。因此它非常适合处理一下一些场景:
1. 有大量的任务,因此在一个时刻至少有一个任务要运行;
2. 任务执行大量的I/O操作;
3. 任务之间相互独立,以至于任务内部的交互很少。
而网络服务就特别具有这些特点,因此可以是该模型的典型代表。