我在这里关注Tornado教程: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)
然而,在 waiter1退出后,waiter2总是醒来并开始工作。
我还试图两次致电IOLoop.current().run_sync()
,但龙卷风抛出RuntimeError: IOLoop has already started.
有人可以告诉我,异步启动线程的正确代码是什么?谢谢!
修改
答案指出sleep
应替换为gen.sleep
。对于我发布的代码段,这是完全正确的,所以谢谢你。
但是,此处的sleep()
仅用于说明目的。我真正想要的是waiter()
和waiter2()
同时进行长时间阻止处理 。我怎样才能做到这一点?
答案 0 :(得分:1)
您无法在代码中调用time.sleep
,因为这么长的阻止调用会干扰龙卷风的IOLoop
工作方式。将time.sleep
的调用替换为tornado.gen.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)