我正在关注龙卷风教程: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)