在Twisted中,两个或多个协同程序是否可以等待相同的延迟?

2024-09-24 22:24:12 发布

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

我正在尝试使用一个延迟来向可能正在等待它的多个协同程序发出任务结束的信号。我希望threading.Event中的事件具有相同的行为。协同路由等待,但只有一个获得被触发延迟的结果。代码示例:

from twisted.internet import defer, task, reactor

async def test(d):
    print("Awaiting")
    print(f"Await finished: {await d}")

d = defer.Deferred()
defer.ensureDeferred(test(d))
defer.ensureDeferred(test(d))
task.deferLater(reactor, 1, d.callback, 'Deferred Fired')

reactor.run()

产出:

Awaiting
Awaiting
Await finished: Deferred Fired
Await finished: None

我期待着:

Awaiting
Awaiting
Await finished: Deferred Fired
Await finished: Deferred Fired

但当一个协同程序等待两次或更多次时,它可以正常工作:

async def test(d):
    print("Awaiting")
    print(f"Await finished: {await d}")
    print(f"Await finished: {await d}")

d = defer.Deferred()
defer.ensureDeferred(test(d))
task.deferLater(reactor, 1, d.callback, 'Deferred Fired')

Tags: testtaskasyncdefawaitdeferreactorprint
1条回答
网友
1楼 · 发布于 2024-09-24 22:24:12

您试图使用延迟作为同步的方法,但这并不是它真正的目的,至少不是它们自己。我假设您想像使用^{}一样使用Deferred?这是我通常看到的范例:

from dataclasses import dataclass, field
from typing import List

from twisted.internet import defer, reactor

@dataclass
class Thing:

    deferred_list: List[defer.Deferred] = field(default_factory=list)

    def notifyFinished(self) -> defer.Deferred:
        deferred = defer.Deferred()
        self.deferred_list.append(deferred)
        return deferred

    def finish(self):
        for index, deferred in enumerate(self.deferred_list):
            deferred.callback(index + 1)
        self.deferred_list = []

async def doSomethingElse(d):
    print("[!] awaiting...")
    print(f"[x] done waiting: {await d}")

def main():
    thing = Thing()
    for _ in range(5):
        d = thing.notifyFinished()
        defer.ensureDeferred(doSomethingElse(d))
    reactor.callLater(5, thing.finish)
    reactor.run()

main()

这里我们有一个函数,它返回一个延迟/未来(即notifyFinished),跟踪那些延迟的,并且一旦一个作业完成,调用一个表示作业结束的函数(即finishDeferred只打算触发一次(Future也可能,但不要引用我的话),因此使用此方法可以确保返回单个Deferred对象并同时触发

相关问题 更多 >