线程在上下文管理器__exit__后仍运行其成员函数是否安全?
关于with语句作用域结束后线程仍访问对象的安全性分析
先看你给出的示例代码:
import threading import time class Foo: def __init__(self, delay): self._delay = delay def __enter__(self): return self def __exit__(self, type, value, traceback): pass def bar(self): time.sleep(self._delay) print("done") with Foo(2) as my_foo: thread = threading.Thread(target=my_foo.bar) thread.start() time.sleep(3)
安全性分析
这个操作是安全的,不会出现悬空引用或未定义行为,原因如下:
- Python的垃圾回收依赖引用计数,只要有活跃引用指向对象,它就不会被销毁。这里线程的
target绑定了my_foo.bar——这是一个绑定方法,会自动保留对my_foo实例的引用,所以在线程运行期间,my_foo的引用计数不会归零,对象始终存在。 - 示例中
Foo类的__exit__方法是空实现,没有清理实例的任何内部属性或资源,所以哪怕with块结束,实例的状态依然完整,线程里的bar方法可以正常访问self._delay并执行逻辑。
注意事项
如果后续给__exit__方法添加了资源清理逻辑(比如关闭文件句柄、释放网络连接、清空实例属性等),那线程在with块结束后访问这些被清理的资源,就会引发错误。但当前示例不存在这种情况,所以完全可以正常运行。
内容的提问来源于stack exchange,提问作者Tobias Hermann
相关产品推荐
相关产品推荐

