协程与资源获取的结合似乎会带来一些意想不到的(或不直观的)后果。
基本的问题是这样的事情是否有效:
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()