龙卷风:如何启动异步线程



我正在关注龙卷风教程:http://www.tornadoweb.org/en/stable/locks.html#tornado.locks.condition

现在而不是一个服务员,我想要两个线程等待相同的条件变量。释放条件后,我希望线程开始进行工作异步

这是我尝试这样做的尝试:

from time import sleep
from tornado import gen
from tornado.ioloop import IOLoop
from tornado.locks import Condition
condition = Condition()
@gen.coroutine
def waiter():
    print('1: waiting')
    yield condition.wait()  # Yield a Future.
    print('1: finish waiting')
    for i in range(5):
        sleep(1)
        print('1: doing work', i)
@gen.coroutine
def waiter2():
    print('2: waiting')
    yield condition.wait()  # Yield a Future.
    print('2: finish waiting')
    for i in range(5):
        sleep(1)
        print('2: doing work', i)
@gen.coroutine
def notifier():
    print("About to notify")
    sleep(2)
    condition.notify_all()
    print("Done notifying")
@gen.coroutine
def runner():
    # combines the futures
    yield [waiter(), waiter2(), notifier()]
IOLoop.current().run_sync(runner)

但是,wateer2总是醒来,并在 waiter1退出后开始工作

我也尝试两次致电IOLoop.current().run_sync(),但龙卷风扔RuntimeError: IOLoop has already started.

任何人都可以向我展示什么是正确的代码,以异步启动线程?谢谢!

编辑

答案指出sleep应由gen.sleep代替。对于我发布的代码段,这是完全正确的,所以谢谢您。

但是,这里的sleep()仅出于说明目的。我真正想要的是waiter()waiter2()同时进行长期阻塞处理。我该如何实现?

您无法在代码中调用time.sleep,因为这样的较长的阻止呼叫从根本上讲龙卷风的IOLoop工作方式。用tornado.gen.sleep coroutine替换给time.sleep的电话,您的代码正常工作:

from time import sleep
from tornado import gen
from tornado.ioloop import IOLoop
from tornado.locks import Condition
condition = Condition()
@gen.coroutine
def waiter():
    print('1: waiting')
    yield condition.wait()  # Yield a Future.
    print('1: finish waiting')
    for i in range(5):
        yield gen.sleep(1)
        print('1: doing work', i)
@gen.coroutine
def waiter2():
    print('2: waiting')
    yield condition.wait()  # Yield a Future.
    print('2: finish waiting')
    for i in range(5):
        yield gen.sleep(1)
        print('2: doing work', i)
@gen.coroutine
def notifier():
    print("About to notify")
    yield gen.sleep(2)
    condition.notify_all()
    print("Done notifying")
@gen.coroutine
def runner():
    # combines the futures
    yield [waiter(), waiter2(), notifier()]
IOLoop.current().run_sync(runner)

最新更新