代码之家  ›  专栏  ›  技术社区  ›  manuele

使用扭曲矩阵的异步执行

  •  2
  • manuele  · 技术社区  · 8 年前

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

    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 回复  |  直到 8 年前
        1
  •  1
  •   Jean-Paul Calderone    8 年前

    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公司 不在中阻塞 时间睡眠() 呼叫相反,它将控制权交给了反应堆。 deferLater(...) 返回a 推迟 在给定的延迟之后,将为您触发给定函数的结果(在这种情况下,函数是不相关的,因为您只想睡觉,但是 deferLater 要求 一些 函数)。

    与…结合 内联回调 ,这会让你在没有 舞台调度 反应堆螺纹。随着时间的推移,反应堆可以自由地找到其他事件进行处理,直到 延迟(…) 推迟 开火。当这种情况发生时,可以在内部继续执行 sqrt公司 并且可以继续计算。当然,请注意,计算本身仍然是阻塞的。然而,由于它是一个简单的整数乘法,它可能不会阻塞足够长的时间。

    这个 推迟 解决方案特定于 time.sleep . 如果您有其他形式的阻塞,您可能需要了解解决它们的其他API。

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