协程和资源获取的结合似乎会产生一些意想不到的(或不直观的)后果。
基本问题是这样的事情是否有效:
def coroutine():
with open(path, 'r') as fh:
for line in fh:
yield line
它确实如此。(你可以测试一下!)
更深层次的担忧是,with
它应该是 的替代品finally
,您可以确保在块的末尾释放资源。协程可以在块内暂停和恢复执行,那么冲突是如何解决的呢?with
例如,如果您在协程尚未返回时打开一个在协程内部和外部都具有读/写功能的文件:
def coroutine():
with open('test.txt', 'rw+') as fh:
for line in fh:
yield line
a = coroutine()
assert a.next() # Open the filehandle inside the coroutine first.
with open('test.txt', 'rw+') as fh: # Then open it outside.
for line in fh:
print 'Outside coroutine: %r' % repr(line)
assert a.next() # Can we still use it?
更新
在前面的示例中,我打算进行写锁定文件句柄争用,但由于大多数操作系统为每个进程分配文件句柄,因此不会出现争用。(感谢@Miles 指出这个例子并没有多大意义。)这是我修改后的例子,它显示了一个真正的死锁情况:
import threading
lock = threading.Lock()
def coroutine():
with lock:
yield 'spam'
yield 'eggs'
generator = coroutine()
assert generator.next()
with lock: # Deadlock!
print 'Outside the coroutine got the lock'
assert generator.next()