使用扭曲矩阵的异步执行

时间:2018-02-09 15:51:26

标签: python python-2.7 asynchronous twisted

我试图开发一个简单的扭曲矩阵示例,目的是执行函数的异步执行,但打印接缝告诉我执行是同步还是按顺序执行,我的误解在哪里?

from twisted.internet.defer import inlineCallbacks, returnValue
import time, random

def _print_(x):
    print "BAR", x

@inlineCallbacks
def sqrt(x):
    time.sleep(random.random())
    r = yield x*2
    print "FOO", r
    returnValue(r)

if __name__=='__main__':

    for dd in map(sqrt, range(10)):
        dd.addCallback(_print_)

1 个答案:

答案 0 :(得分:1)

Twisted不会将阻塞代码转换为非阻塞代码,也不会将同步代码转换为异步代码。它为您提供了编写异步代码的工具。

phpPgAdmininlineCallbacks基本相同,但使用不同的API。它并没有改变Twisted的单线程,协作多任务特性。

您按顺序发布的程序会在范围(10)的整数上调用sqrt。每次调用Deferred都会随机休眠一段时间,然后计算结果。计算都发生在一个线程中,因此一次只能发生一件事。当睡眠发生时,没有别的。

您可以使用Twisted的助手之一替换阻止sqrt来电:

time.sleep()

现在from twisted.internet.task import deferLater from twisted.internet import reactor @inlineCallbacks def sqrt(x): yield deferLater(reactor, random.random(), lambda: None) r = yield x*2 print "FOO", r returnValue(r) 不会阻止sqrt来电。相反,它放弃了对反应堆的控制。 time.sleep()返回一个deferLater(...),在给定的延迟后,将使用给定函数的结果为您触发(在这种情况下,函数是无关紧要的,因为您只想睡觉,但是Deferred需要一些功能。)

结合deferLater,这会给你一个"睡眠"没有阻塞反应堆线程。在时间过去之前,反应堆可以自由查找要处理的其他事件,直到inlineCallbacks deferLater(...)触发为止。当发生这种情况时,执行可以在Deferred内恢复,计算可以继续进行。当然,请注意计算本身仍然是阻塞的。但是,由于它是一个简单的整数乘法,它可能不会长时间阻塞。

sqrt解决方案特定于deferLater。如果您有其他形式的阻止,您可能需要了解其他解决这些问题的API。

您可能还想阅读How do I add two integers together with Twisted?