通过阅读http://bugs.python.org/msg160297,我可以看到一个由Stephen White编写的简单脚本,该脚本演示了python线程是如何处理这个异常的
Exception AttributeError: AttributeError("'_DummyThread' object has no attribute '_Thread__block'",) in <module 'threading'
考虑到Stephen White的源代码(http://bugs.python.org/file25511/bad thread.py)
import os
import thread
import threading
import time
def t():
threading.currentThread() # Populate threading._active with a DummyThread
time.sleep(3)
thread.start_new_thread(t, ())
time.sleep(1)
pid = os.fork()
if pid == 0:
os._exit(0)
os.waitpid(pid, 0)
我们如何重新编写它以解决此错误?
发生The bug的原因是,当一个人在外部线程上调用
threading.currentThread()
时,由threading
API创建的伪线程对象与threading._after_fork
函数(在调用os.fork()
后调用以清理资源)之间的交互不正确。为了在不修改Python源代码的情况下解决这个bug,monkey补丁
threading._DummyThread
使用了__stop
的无操作实现:错误的原因最好在注释中通过Richard Oudkerk和cooyeah缩小。发生的情况如下:
threading
模块允许从不是由threading
API调用创建的线程调用threading.currentThread()
。然后,它返回一个“伪线程”实例,该实例支持Thread
API的非常有限的子集,但对于标识当前线程仍然有用。threading._DummyThread
作为Thread
的子类实现。Thread
实例通常包含一个内部可调用(self.__block
),它保留对为实例分配的操作系统级锁的引用。由于最终可能使用self.__block
的公共Thread
方法都被_DummyThread
重写,因此_DummyThread
的构造函数有意通过删除self.__block
来释放操作系统级锁。threading._after_fork
中断封装,并在所有注册的线程(包括虚拟线程)上调用私有的Thread.__stop
方法,其中__stop
从未打算被调用。(它们不是由Python启动的,因此它们的停止也不是由Python管理的。)由于虚拟线程不知道__stop
,所以它们从Thread
继承它,并且实现很高兴地访问__block
实例中不存在的私有_DummyThread
属性。此访问最终导致错误。删除} not to break 将修复2.7分支中的错误。3.x分支,其中}'s ^{} to do nothing 修复它。
__block
时,modifying ^{__stop
拼写为_stop
,因此受到保护,通过overriding ^{相关问题 更多 >
编程相关推荐