tornado.locks.Lock release
<p>The tornado example gives the following example for locks:</p>

<pre><code>&gt;&gt;&gt; from tornado import gen, locks
&gt;&gt;&gt; lock = locks.Lock()
&gt;&gt;&gt;
&gt;&gt;&gt; @gen.coroutine
... def f():
...    with (yield lock.acquire()):
...        # Do something holding the lock.
...        pass
...
...    # Now the lock is released.
</code></pre>

<p>Do you need to release the lock manually after the with or is that the purpose of using the with statement in that block? If this is the case why is there a separate release() and does this function need to be yielded?</p>

<p>Right, the <code>with</code> statement ensures the Lock is released, no need to call <code>release</code> yourself.</p>

<p><code>release</code> is naturally non-blocking -- your coroutine can complete a call to <code>release</code> without waiting for any other coroutines -- therefore <code>release</code> does not require a <code>yield</code> statement. You can determine that for yourself by noticing the return value of <code>release</code> is <code>None</code>, whereas the return value of <code>acquire</code> is a Future.</p>

python tornado