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