deferToThread vs Deferred()

时间:2014-02-19 14:51:30

标签: python-2.7 twisted deferred twisted.internet

我想了解以下2个代码段会发生什么 -

SNIPPET#1

from twisted.internet import threads, defer, reactor

def proc1(a):
    while True:
        print "Proc----------1"

def proc2(a):
    while True:
        print "Proc----------2"

def proc3(a):
    while True:
        print "Proc----------3"

d1 = threads.deferToThread(proc1)
d2 = threads.deferToThread(proc2)
d3 = threads.deferToThread(proc3)

reactor.run()

我的理解是所有线程并行运行,输出是=>混合所有过程的stdout

剪断#2

from twisted.internet import threads, defer, reactor

def proc1(a):
    while True:
        print "Proc----------1"

def proc2(a):
    while True:
        print "Proc----------2"

def proc3(a):
    while True:
        print "Proc----------3"



d1 = defer.Deferred()
d2 = defer.Deferred()
d3 = defer.Deferred()

d1.addCallback(proc1)
d2.addCallback(proc2)
d3.addCallback(proc3)

d1.callback('a')
d2.callback('a')
d3.callback('a')

reactor.run()

对于这个片段 - 每个延迟的回调都是一个接一个地触发,就输出而言,只有proc1 stdouts无限期地倾倒。

如果我错了,请纠正我。基本上我想要理解和确认的是Deferred对象是一个接一个地触发而deferToThread是由名称线程并行运行。

2 个答案:

答案 0 :(得分:4)

  

如果我错了,请纠正我。基本上我想要理解和确认的是Deferred对象是一个接一个地触发而deferToThread是由名称线程并行运行。

这不完全正确,但它有点接近。以下是触发Deferreds的代码:

d1.callback('a')
d2.callback('a')
d3.callback('a')

你一个接一个地触发它们。关于这一点没有什么特别的或神秘的。这就是Python的工作原理。

延迟与线程没有任何关系。它们不会自动使代码无阻塞或异步或多线程。他们只保留一个函数列表(您使用addCallback方法添加到该列表中),然后调用该列表中的函数(当您使用callback方法时)。

答案 1 :(得分:1)

你的理解还可以。

Snippet 1将同时运行所有过程(每个过程都在自己的线程中)。这三个程序必须是线程安全的。

Snippet 2将在reactor线程中一个接一个地运行这些过程。只有当一个过程完成时,reactor线程才会传递给下一个延迟,因此开始执行下一个过程。

如果其中一个延迟是扭曲的一部分,比如通过网络访问某些东西,当它阻塞时,反应堆将继续进行下一个未阻止的延迟,并最终在解除阻塞之后的某个时间拾取阻塞的反应堆。

您不必担心其中一个进程会干扰另一个进程(假设您没有其他代码调用它们或多个反应器调用它们)