python - 理解 python 线程错误

标签 python python-multithreading

阅读 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 源代码的情况下解决该错误,使用 __stop 的空操作实现猴子补丁 threading._DummyThread:

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

最好通过 Richard Oudkerk 在评论中缩小错误的原因。和 cooyeah .发生的情况如下:

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

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

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

该错误已在 2.7 分支中由 modifying Thread.__stop not to break 修复当 __block 被删除时。 3.x 分支,其中 __stop 拼写为 _stop 并因此受到保护,由 overriding _DummyThread's _stop to do nothing 修复它.

关于python - 理解 python 线程错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13193278/

相关文章:

python - 内存分配失败: growing buffer - Python

scikit-learn - 多处理支持的并行循环不能嵌套在线程下

Python 多处理-为已完成的进程分配新函数?

python - 如何读取文本文件并将其逐字写入python中的另一个文件?

python - ftplib 检查文件是否是文件夹?

python - 在没有验证集和图像归一化的情况下训练 Keras 模型

python - 包含 GIL 的简单 Python 函数

python - 优化算法以处理元组、集合和字典

python - bool 掩码 Tensorflow,tf.boolean_mask - 保持原始张量的尺寸

python - pow 函数使用 ThreadPoolExecutor 阻塞所有线程