协程和资源获取的组合似乎可能具有一些无意的(或不直观的)后果。
基本问题是这样的东西是否有效:
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?
Update
我之前在谈论写锁定的文件句柄争用问题,但是由于大多数操作系统都是按进程分配文件句柄的,所以在那里不会有争用。 (感谢 @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()