我正在尝试开发一个简单的扭曲矩阵示例,目的是执行函数的异步执行,但打印接缝告诉我执行是同步的还是按顺序执行的,我的误解在哪里?
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_)
最佳答案
Twisted 不会将阻塞代码转换为非阻塞代码,也不会将同步代码转换为异步代码。它为您提供了编写异步代码的工具。
inlineCallbacks
本质上与 Deferred
相同,但 API 不同。它不会改变 Twisted 的单线程、协作多任务处理特性。
您发布的程序按顺序对范围 (10) 中的整数调用 sqrt。每次调用 sqrt
都会随机休眠一段时间,然后计算结果。计算全部发生在单个线程中,因此一次只能发生一件事。当 sleep 发生时,没有其他事情发生。
您可以做的是使用 Twisted 的助手之一来替换阻塞的 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()
调用。相反,它放弃了对 react 堆的控制。 deferLater(...)
返回一个 Deferred
,它将在给定延迟后为您触发,并返回给定函数的结果(在这种情况下,该函数是无关紧要的,因为您只想 sleep ,但 deferLater
需要一些功能)。
与inlineCallbacks
结合使用,这可以让您“休眠”,而不会阻塞 react 器线程。随着时间的流逝, react 堆可以自由地寻找其他事件进行处理,直到 deferLater(...)
Deferred
触发。发生这种情况时,可以在 sqrt
内恢复执行,并且可以继续进行计算。当然,请注意计算本身仍然是阻塞的。但是,由于它是一个简单的整数乘法,它可能不会阻塞足够长的时间。
deferLater
解决方案特定于 time.sleep
。如果您有其他形式的阻塞,您可能需要了解解决这些问题的其他 API。
关于python - 使用扭曲矩阵的异步执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48709502/