2015-02-14 19:30:48 +00:00
|
|
|
``tornado.locks`` -- Synchronization primitives
|
|
|
|
===============================================
|
|
|
|
|
|
|
|
.. versionadded:: 4.2
|
|
|
|
|
2015-03-25 10:18:32 +00:00
|
|
|
Coordinate coroutines with synchronization primitives analogous to those the
|
|
|
|
standard library provides to threads.
|
|
|
|
|
|
|
|
*(Note that these primitives are not actually thread-safe and cannot be used in
|
|
|
|
place of those from the standard library--they are meant to coordinate Tornado
|
|
|
|
coroutines in a single-threaded app, not to protect shared objects in a
|
|
|
|
multithreaded app.)*
|
|
|
|
|
2015-03-27 10:20:40 +00:00
|
|
|
.. testsetup::
|
|
|
|
|
|
|
|
from tornado import ioloop, gen, locks
|
|
|
|
io_loop = ioloop.IOLoop.current()
|
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
.. automodule:: tornado.locks
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
Condition
|
|
|
|
---------
|
|
|
|
.. autoclass:: Condition
|
|
|
|
:members:
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
With a `Condition`, coroutines can wait to be notified by other coroutines:
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
.. testcode::
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
condition = locks.Condition()
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
@gen.coroutine
|
|
|
|
def waiter():
|
|
|
|
print("I'll wait right here")
|
|
|
|
yield condition.wait() # Yield a Future.
|
|
|
|
print("I'm done waiting")
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
@gen.coroutine
|
|
|
|
def notifier():
|
|
|
|
print("About to notify")
|
|
|
|
condition.notify()
|
|
|
|
print("Done notifying")
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
@gen.coroutine
|
|
|
|
def runner():
|
|
|
|
# Yield two Futures; wait for waiter() and notifier() to finish.
|
|
|
|
yield [waiter(), notifier()]
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
io_loop.run_sync(runner)
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
.. testoutput::
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
I'll wait right here
|
|
|
|
About to notify
|
|
|
|
Done notifying
|
|
|
|
I'm done waiting
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
`wait` takes an optional ``timeout`` argument, which is either an absolute
|
|
|
|
timestamp::
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
io_loop = ioloop.IOLoop.current()
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
# Wait up to 1 second for a notification.
|
|
|
|
yield condition.wait(deadline=io_loop.time() + 1)
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
...or a `datetime.timedelta` for a deadline relative to the current time::
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
# Wait up to 1 second.
|
|
|
|
yield condition.wait(deadline=datetime.timedelta(seconds=1))
|
2015-03-25 10:18:32 +00:00
|
|
|
|
2015-03-26 10:31:57 +00:00
|
|
|
The method raises `tornado.gen.TimeoutError` if there's no notification
|
|
|
|
before the deadline.
|
2015-03-27 10:17:31 +00:00
|
|
|
|
|
|
|
Event
|
|
|
|
-----
|
|
|
|
.. autoclass:: Event
|
|
|
|
:members:
|
|
|
|
|
2015-03-28 10:02:32 +00:00
|
|
|
A coroutine can wait for an event to be set. Once it is set, calls to
|
|
|
|
``yield event.wait()`` will not block unless the event has been cleared:
|
2015-03-27 10:17:31 +00:00
|
|
|
|
|
|
|
.. testcode::
|
|
|
|
|
|
|
|
event = locks.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()]
|
|
|
|
|
|
|
|
io_loop.run_sync(runner)
|
|
|
|
|
|
|
|
.. testoutput::
|
|
|
|
|
|
|
|
Waiting for event
|
|
|
|
About to set the event
|
|
|
|
Not waiting this time
|
|
|
|
Done
|