使用twisted矩阵的异步执行

2024-10-06 12:06:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试开发一个简单的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_)

Tags: 函数import目的示例time顺序deftwisted
1条回答
网友
1楼 · 发布于 2024-10-06 12:06:18

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(...)返回一个Deferred,它将在给定的延迟后为您激发给定函数的结果(在这种情况下,函数是不相关的,因为您只想睡眠,但是deferLater需要一些函数)。你知道吗

inlineCallbacks相结合,这将为您提供一个“睡眠”,而不会阻塞reactor线程。当时间流逝时,反应器可以自由地找到其他事件来处理,直到deferLater(...)Deferred触发。当这种情况发生时,可以在sqrt内继续执行,并且可以继续计算。当然,请注意,计算本身仍然是阻塞的。然而,由于它是一个简单的整数乘法,它可能不会阻塞足够长的时间。你知道吗

deferLater解决方案特定于time.sleep。如果您有其他形式的阻塞,您可能需要了解解决它们的其他api。你知道吗

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

相关问题 更多 >