python - 使用扭曲矩阵的异步执行

标签 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_)

最佳答案

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。

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

关于python - 使用扭曲矩阵的异步执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48709502/

相关文章:

c++ - C++ 中安全异步回调的模式

python - 将日期转换为小时

python - 最好将项目添加到集合中,还是将最终列表转换为集合?

python - 使用正则表达式从 python 中的 readline() 获取一些子字符串

python - 从 Python 中的两个列表创建(嵌套)列表

python - 格式化 Unicode 的 Unicode 表示?

javascript - Angular Controller 完成加载异步函数后加载 html View

python - 使用 FFMPEG 命令读取帧并使用 opencv 中的 inshow 函数显示

python - 如何通过搜索元素的属性在 Python 中使用 ElementTree 删除 xml 中的节点?

javascript - 在构造函数中调用异步函数。