tornado.locks
- 同步原语¶
4.2 新版功能.
协调程序与类似于标准库提供给线程的同步原语。
(请注意,这些原语实际上不是线程安全的,不能用来代替标准库中的那些 - 它们用于在单线程应用程序中协调Tornado协程,而不是保护多线程应用程序中的共享对象。)
条件¶
-
class
tornado.locks.
Condition
[源代码]¶ 条件允许一个或多个协同程序等待直到通知。
像标准
threading.Condition
,但不需要获取和释放的基础锁。使用
Condition
,协同程序可以等待其他协程通知:from tornado import gen from tornado.ioloop import IOLoop from tornado.locks import Condition condition = Condition() @gen.coroutine def waiter(): print("I'll wait right here") yield condition.wait() # Yield a Future. print("I'm done waiting") @gen.coroutine def notifier(): print("About to notify") condition.notify() print("Done notifying") @gen.coroutine def runner(): # Yield two Futures; wait for waiter() and notifier() to finish. yield [waiter(), notifier()] IOLoop.current().run_sync(runner)
I'll wait right here About to notify Done notifying I'm done waiting
wait
接受可选的timeout
参数,它是一个绝对时间戳:io_loop = IOLoop.current() # Wait up to 1 second for a notification. yield condition.wait(timeout=io_loop.time() + 1)
...或
datetime.timedelta
相对于当前时间的超时:# Wait up to 1 second. yield condition.wait(timeout=datetime.timedelta(seconds=1))
如果在截止日期之前没有通知,该方法提出
tornado.gen.TimeoutError
。
事件¶
-
class
tornado.locks.
Event
[源代码]¶ 事件阻止协程,直到其内部标志设置为True。
类似于
threading.Event
。协同程序可以等待要设置的事件。一旦设置,对
yield event.wait()
的调用将不会阻塞,除非事件已被清除:from tornado import gen from tornado.ioloop import IOLoop from tornado.locks import Event event = Event() @gen.coroutine def waiter(): print("Waiting for event") yield event.wait() print("Not waiting this time") yield event.wait() print("Done") @gen.coroutine def setter(): print("About to set the event") event.set() @gen.coroutine def runner(): yield [waiter(), setter()] IOLoop.current().run_sync(runner)
Waiting for event About to set the event Not waiting this time Done
-
wait
(timeout=None)[源代码]¶ 阻塞直到内部标志为真。
返回一个未来,它在超时后引发
tornado.gen.TimeoutError
。
-
信号¶
-
class
tornado.locks.
Semaphore
(value=1)[源代码]¶ 在锁定之前可以获取固定次数的锁。
信号量管理一个表示
release
呼叫数量减去acquire
呼叫数量加上一个初始值的计数器。如果需要,acquire
方法阻塞,直到它可以返回而不使计数器为负。信号量限制对共享资源的访问。允许一次访问两个工人:
from tornado import gen from tornado.ioloop import IOLoop from tornado.locks import Semaphore sem = Semaphore(2) @gen.coroutine def worker(worker_id): yield sem.acquire() try: print("Worker %d is working" % worker_id) yield use_some_resource() finally: print("Worker %d is done" % worker_id) sem.release() @gen.coroutine def runner(): # Join all workers. yield [worker(i) for i in range(3)] IOLoop.current().run_sync(runner)
Worker 0 is working Worker 1 is working Worker 0 is done Worker 2 is working Worker 1 is done Worker 2 is done
工作器0和1允许同时运行,但工作器2等待,直到信号量被工作器0释放一次。
acquire
是一个上下文管理器,所以worker
可以写成:@gen.coroutine def worker(worker_id): with (yield sem.acquire()): print("Worker %d is working" % worker_id) yield use_some_resource() # Now the semaphore has been released. print("Worker %d is done" % worker_id)
在Python 3.5中,信号量本身可以用作异步上下文管理器:
async def worker(worker_id): async with sem: print("Worker %d is working" % worker_id) await use_some_resource() # Now the semaphore has been released. print("Worker %d is done" % worker_id)
在 4.3 版更改: 在Python 3.5中添加了
async with
支持。-
acquire
(timeout=None)[源代码]¶ 递减计数器。返回未来。
如果计数器为零并等待
release
,则阻塞。未来在截止日期之后提高TimeoutError
。
-
BoundedSemaphore¶
-
class
tornado.locks.
BoundedSemaphore
(value=1)[源代码]¶ 防止release()被调用次数过多的信号量。
如果
release
将信号量的值增加超过初始值,则它提高ValueError
。信号量主要用于保护有限容量的资源,因此信号量释放太多次是一个错误的迹象。-
acquire
(timeout=None)¶ 递减计数器。返回未来。
如果计数器为零并等待
release
,则阻塞。未来在截止日期之后提高TimeoutError
。
-
锁¶
-
class
tornado.locks.
Lock
[源代码]¶ 协同锁。
锁开始解锁,
acquire
立即锁定。当它被锁定时,产生acquire
的协同程序等待,直到另一个协同程序调用release
。释放解锁的锁提高
RuntimeError
。acquire
在所有Python版本中支持上下文管理器协议:>>> from tornado import gen, locks >>> lock = locks.Lock() >>> >>> @gen.coroutine ... def f(): ... with (yield lock.acquire()): ... # Do something holding the lock. ... pass ... ... # Now the lock is released.
在Python 3.5中,
Lock
还支持异步上下文管理器协议。注意,在这种情况下没有acquire
,因为async with
包括yield
和acquire
(正如它与threading.Lock
一样):>>> async def f(): ... async with lock: ... # Do something holding the lock. ... pass ... ... # Now the lock is released.
在 4.3 版更改: 在Python 3.5中添加了
async with
支持。-
acquire
(timeout=None)[源代码]¶ 尝试锁定。返回未来。
返回一个未来,它在超时后引发
tornado.gen.TimeoutError
。
-
release
()[源代码]¶ 开锁。
第一个在线等待
acquire
的协程获取锁。如果未锁定,请提出
RuntimeError
。
-