发生该错误的原因是,@H_502_1@threading调用@H_502_1@threading.currentThread()一个外部线程时,由API创建的虚拟线程对象与该@H_502_1@threading._after_fork函数之间的不良交互,该函数在调用后被调用以清理资源@H_502_1@os.fork()。
要在不修改Python源代码的情况下解决该错误,请@H_502_1@threading._DummyThread使用no-op实现的Monkey-patch@H_502_1@__stop:
@H_502_1@import threading threading._DummyThread._Thread__stop = lambda x: 42
Richard Oudkerk和cooyeah在评论中最好缩小该错误的原因。发生了以下情况:
该@H_502_1@threading模块允许@H_502_1@threading.currentThread()从非@H_502_1@threadingAPI调用创建的线程中调用。然后,它返回一个“虚拟线程”实例,该实例支持@H_502_1@ThreadAPI的一个非常有限的子集,但对于标识当前线程仍然有用。
@H_502_1@threading._DummyThread被实现为的子类@H_502_1@Thread。@H_502_1@Thread实例通常包含一个内部可调用对象(@H_502_1@self.__block),该可调用对象始终引用为该实例分配的OS级锁。由于@H_502_1@Thread可能最终使用的公共方法@H_502_1@self.__block全部被覆盖@H_502_1@_DummyThread,因此@H_502_1@_DummyThread的构造方法通过删除故意释放了OS级锁@H_502_1@self.__block。
@H_502_1@threading._after_fork破坏封装并@H_502_1@Thread.__stop在所有注册的线程(包括虚拟线程)上调用私有方法,这些线程@H_502_1@__stop决不应该被调用。(它们不是由Python启动的,因此它们的停止也不由Python管理。)由于虚拟线程不知道@H_502_1@__stop,因此它们从继承它@H_502_1@Thread,并且该实现愉快地访问实例@H_502_1@__block中不存在的private属性。@H_502_1@_DummyThread。该访问最终导致错误。
通过修改Thread.__stop
@H_502_1@__block删除时不中断的方式,该错误已在2.7分支中得到修复。3.X分支,在那里@H_502_1@__stop被拼成@H_502_1@_stop,因此保护,通过修复它覆盖_DummyThread
的_stop
什么也不做。