了解python线程错误

2024-05-20 02:45:01 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我们如何重新编写它以解决此错误?


Tags: orgimport脚本httptimeossleeppid
1条回答
网友
1楼 · 发布于 2024-05-20 02:45:01

发生The bug的原因是,当一个人在外部线程上调用threading.currentThread()时,由threadingAPI创建的伪线程对象与threading._after_fork函数(在调用os.fork()后调用以清理资源)之间的交互不正确。

为了在不修改Python源代码的情况下解决这个bug,monkey补丁threading._DummyThread使用了__stop的无操作实现:

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

错误的原因最好在注释中通过Richard Oudkerkcooyeah缩小。发生的情况如下:

  1. threading模块允许从不是由threadingAPI调用创建的线程调用threading.currentThread()。然后,它返回一个“伪线程”实例,该实例支持ThreadAPI的非常有限的子集,但对于标识当前线程仍然有用。

  2. threading._DummyThread作为Thread的子类实现。Thread实例通常包含一个内部可调用(self.__block),它保留对为实例分配的操作系统级锁的引用。由于最终可能使用self.__block的公共Thread方法都被_DummyThread重写,因此_DummyThread的构造函数有意通过删除self.__block来释放操作系统级锁。

  3. threading._after_fork中断封装,并在所有注册的线程(包括虚拟线程)上调用私有的Thread.__stop方法,其中__stop从未打算被调用。(它们不是由Python启动的,因此它们的停止也不是由Python管理的。)由于虚拟线程不知道__stop,所以它们从Thread继承它,并且实现很高兴地访问__block实例中不存在的私有_DummyThread属性。此访问最终导致错误。

删除__block时,modifying ^{} not to break将修复2.7分支中的错误。3.x分支,其中__stop拼写为_stop,因此受到保护,通过overriding ^{}'s ^{} to do nothing修复它。

相关问题 更多 >