阅读http://bugs.python.org/msg160297 ,我可以看到由斯蒂芬·怀特写了一个简单的脚本,这表明蟒蛇线程如何虫子了这个异常
Exception AttributeError: AttributeError("'_DummyThread' object has no attribute '_Thread__block'",) in <module 'threading'
鉴于斯蒂芬·怀特的源代码(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)
如何将我们把它重新写那么这个错误得到解决?
该错误的发生是因为在创建虚拟线程对象之间的互动不良的threading
API时,一个叫threading.currentThread()
在国外螺纹和threading._after_fork
后调用函数,称为清理资源os.fork()
。
要解决这个bug,而无需修改Python的来源,猴子补丁threading._DummyThread
与无操作执行__stop
:
import threading
threading._DummyThread._Thread__stop = lambda x: 42
错误的原因在通过评论,最好缩小理查德奥德柯克和cooyeah 。 什么情况如下:
该threading
模块允许threading.currentThread()
从没有被创建的线程调用threading
API调用。 然后,它返回一个“虚拟线”实例,它支持非常有限的子Thread
API,但仍然是用于识别当前线程是有用的。
threading._DummyThread
被实现为一个子Thread
。 Thread
实例通常含有一个内部可调用( self.__block
),保持参照分配用于该实例的OS级锁。 由于公共Thread
方法可能最终使用self.__block
都是由覆盖_DummyThread
, _DummyThread
的构造故意释放通过删除OS级锁self.__block
。
threading._after_fork
打破了封装和调用私有Thread.__stop
所有注册线程,包括虚拟的,在其中方法__stop
从来就不是被调用。 (他们所不Python开始,所以他们停止不Python的任一管理)。由于虚拟线程不知道__stop
,他们继承它从Thread
,并愉快地执行访问私有__block
一点不属性存在于_DummyThread
实例。 此访问终于导致错误。
该缺陷是由固定在2.7分支修改Thread.__stop
不打破时__block
被删除。 3.X分支,其中__stop
被拼写为_stop
,因此保护,以修复它覆盖_DummyThread
的_stop
什么也不做 。