Understand python threading bug(了解python线程错误)
问题描述
阅读http://bugs.python.org/msg160297,我可以看到Stephen White编写的一个简单脚本,它演示了该异常是如何导致python线程出错的
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)
如何重写以解决此错误?
推荐答案
The bug是因为threading接口在外线程上调用threading.currentThread()时创建的虚拟线程对象与threading._after_fork函数(在调用os.fork()后被调用以清理资源)之间的交互不好。
要在不修改Python源代码的情况下解决该错误,请使用__stop的无操作实现:
import threading
threading._DummyThread._Thread__stop = lambda x: 42
错误的原因最好在Richard Oudkerk和cooyeah的评论中缩小范围。发生的情况如下:
threading模块允许从非由threadingAPI调用创建的线程调用threading.currentThread()。然后,它返回一个"哑线程"实例,该实例支持ThreadAPI的一个非常有限的子集,但对于标识当前线程仍然有用。threading._DummyThread作为Thread的子类实现。Thread实例通常包含一个内部可调用的(self.__block),该内部可调用保持对为该实例分配的操作系统级锁的引用。由于可能最终使用self.__block的公共Thread方法都被_DummyThread覆盖,_DummyThread的构造函数有意通过删除self.__block来释放操作系统级锁。
/li>threading._after_fork打破封装并在所有注册线程上调用私有Thread.__stop方法,包括虚拟线程,其中__stop从未打算被调用。(它们不是由Python启动的,因此它们的停止也不是由Python管理的。)由于伪线程不知道__stop,它们从Thread继承,该实现愉快地访问_DummyThread实例中不存在的私有__block属性。此访问最终导致错误。
删除__block时,通过modifying Thread.__stop not to break修复了2.7分支中的错误。3.x分支将__stop拼写为_stop,因此受保护,并将其修复为overriding _DummyThread's _stop to do nothing。
这篇关于了解python线程错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:了解python线程错误
基础教程推荐
- 用 Python 编写 Fortran 无格式文件 2022-01-01
- numpy float:比算术运算中内置的慢 10 倍? 2022-01-01
- 由Python将MP3转换为MIDI(类型错误:无法加载插件:mtg-Melodia:Melodia) 2022-01-01
- 将 x 轴刻度更改为自定义字符串 2022-01-01
- 尝试制作WhatsApp机器人 2022-01-01
- 与常规 dict 相比,Python manager.dict() 非常慢 2022-01-01
- 使用生成器和迭代器时 Python 多循环失败 2022-01-01
- pyserial - 可以从线程 a 写入串行端口,是否阻塞从线程 b 读取? 2022-01-01
- Discord.py 缺少必需的参数 2022-01-01
- 在 Celery 工作人员中捕获 Heroku SIGTERM 以优雅地关 2022-01-01
