了解蟒蛇线程错误(Understand python threading bug)

2019-07-03 12:53发布

阅读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)

如何将我们把它重新写那么这个错误得到解决?

Answer 1:

该错误的发生是因为在创建虚拟线程对象之间的互动不良的threading API时,一个叫threading.currentThread()在国外螺纹和threading._after_fork后调用函数,称为清理资源os.fork()

要解决这个bug,而无需修改Python的来源,猴子补丁threading._DummyThread与无操作执行__stop

import threading
threading._DummyThread._Thread__stop = lambda x: 42

错误的原因在通过评论,最好缩小理查德奥德柯克和cooyeah 。 什么情况如下:

  1. threading模块允许threading.currentThread()从没有被创建的线程调用threading API调用。 然后,它返回一个“虚拟线”实例,它支持非常有限的子Thread API,但仍然是用于识别当前线程是有用的。

  2. threading._DummyThread被实现为一个子ThreadThread实例通常含有一个内部可调用( self.__block ),保持参照分配用于该实例的OS级锁。 由于公共Thread方法可能最终使用self.__block都是由覆盖_DummyThread_DummyThread的构造故意释放通过删除OS级锁self.__block

  3. threading._after_fork打破了封装和调用私有Thread.__stop所有注册线程,包括虚拟的,在其中方法__stop从来就不是被调用。 (他们所不Python开始,所以他们停止不Python的任一管理)。由于虚拟线程不知道__stop ,他们继承它从Thread ,并愉快地执行访问私有__block一点不属性存在于_DummyThread实例。 此访问终于导致错误。

该缺陷是由固定在2.7分支修改Thread.__stop不打破时__block被删除。 3.X分支,其中__stop被拼写为_stop ,因此保护,以修复它覆盖_DummyThread_stop什么也不做 。



文章来源: Understand python threading bug