Python运行Eel搭配多线程出现RuntimeError错误该如何解决?
问题原因分析
- 根本原因是Eel底层依赖gevent异步框架,gevent的运行环境初始化必须在主线程完成,不能放到子线程里启动。
- 你当前的代码把
eel.start()放到子线程运行,gevent在子线程初始化内部线程池的时候,会尝试调用threading._register_atexit注册退出钩子,但此时主线程的初始化阶段已经走完,Python的atexit注册通道已经关闭,就会抛出对应的RuntimeError错误。 - 多进程能正常运行的原因是每个进程有独立的运行环境,Eel在子进程里相当于单独运行,不存在主线程atexit关闭的问题。
解决方案
方案1:调整线程启动顺序,Eel放在主线程运行
这是最稳妥的方案,把业务逻辑的死循环放到子线程,Eel的启动放在主线程即可,修改后的代码如下:
import eel import threading import time eel.init("web") o = 0 def main0(): global o while True: time.sleep(1) print(o) o += 10 if __name__ == '__main__': # 先启动业务子线程 threading.Thread(target = main0, args=()).start() # Eel启动放在主线程 eel.start("index.html")
方案2:提前初始化gevent组件
如果确实有需要把Eel放到子线程运行的场景,可以在代码最开头提前导入gevent相关组件,避免延迟导入触发atexit注册失败:
# 开头第一行添加这段,提前完成gevent相关组件初始化 from gevent.resolver.thread import ThreadPoolResolver # 后面再写原来的业务代码 import eel import threading import time eel.init("web") def main(): eel.start("index.html") o = 0 def main0(): global o while True: time.sleep(1) print(o) o += 10 if __name__ == '__main__': threading.Thread(target = main0, args=()).start() threading.Thread(target = main, args=()).start()
内容的提问来源于stack exchange,提问作者elit3
相关产品推荐
相关产品推荐

