单线程与多线程的反应堆设计模式

时间:2014-11-09 12:30:36

标签: python multithreading twisted reactor

我一直在阅读反应堆设计模式,特别是在Python Twisted网络框架的上下文中。我对反应堆设计的简单理解是,有一个线程可以等待一个或多个I / O源(或文件描述符)变为可用,然后它将同步循环遍历每个源,执行任何回调为每个来源指定。这意味着如果任何回调本身阻塞,整个程序将阻止。无论如何,一旦所有回调都执行完毕,反应堆就会等待更多的I / O源准备就绪。

与在每个源出现时异步循环,即为每个源启动单独的线程相比,有什么优点和缺点。我想如果所有回调都非常快,这可能效率会降低,因为操作系统现在必须处理管理多个线程并在它们之间进行交换。但似乎现在不可能阻止主程序,并且作为额外的好处,主反应堆可以继续监听来源。简而言之,为什么像Twisted这样的东西不会这样做,而是保持单线程模型呢?

2 个答案:

答案 0 :(得分:3)

  

与在每个源出现时异步循环,即为每个源启动一个单独的线程相比,有什么优点和缺点。

您所描述的基本上是在使用阻塞I / O API的多线程程序中发生的情况。在这种情况下,“reactor”进入内核,“异步循环”是内核完成一些未完成的阻塞操作,释放用户空间线程继续。

与严格的单线程方法相比,这种方法的缺点是线程安全性(即正确性)的复杂性大大增加。

专业人员可以更好地利用多个CPU(但是运行多个单线程事件驱动的流程通常也能提供这种优势)以及使用多线程方法熟悉且舒适(尽管经常是错误的)的程序员数量更多并发。

此外,PyPy团队还致力于提供比传统多线程模型更好的抽象。 PyPy对软件事务内存(STM)的工作可以提供一个系统,在该系统中,工作被异步调度到多个工作线程,而不会违反严格的单线程系统中有效的假设。如果这样做,它可以提供两全其美。

答案 1 :(得分:1)

  

但似乎现在不可能阻止主程序,

我不是一个Python人,而是在Boost的背景下完成了这个。短耳。您正确 - 您的回调需要快速执行并将控制权返回给主反应堆。我们的想法是只在回调中使用异步调用。例如,您不会使用API​​来发送阻止和返回状态代码的IP数据报。相反,您使用非阻塞API来注册成功和失败回调。这使得呼叫发送呼叫立即返回。一旦操作系统处理完数据包,反应堆就会调用成功/失败回调。