背景
在 django 开发的接口服务中需要返回由 matplotlib 生成的图片,第一次页面请求接口正常,刷新页面后出现了以下异常导致服务崩溃,
python
if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
RuntimeError: main thread is not in main loop
这个 RuntimeError: main thread is not in main loop
看起来是 matplotlib 的依赖 tinker 库出现的问题。
问题分析
通常是因为 matplotlib 默认会使用 GUI 后端,而 Django 是一个 Web 框架,在服务器端运行,没有 GUI 环境,且 matplotlib 的 GUI 后端在非主线程的上下文中使用时会出现问题。以下是解决该问题的详细步骤和方法:
matplotlib 默认使用的后端(如 TkAgg)依赖于 GUI 环境,而 Django 运行在服务器端,没有这样的环境。并且在 Django 中,代码执行的线程上下文与 matplotlib 的 GUI 后端不兼容,导致出现 main thread is not in main loop 错误。
解决办法
更改 matplotlib 的后端
将 matplotlib 的后端更改为非 GUI 后端,例如 Agg,它可以在无 GUI 环境下生成图片。
python
import matplotlib
matplotlib.use('Agg') # 在导入 pyplot 之前设置后端
import matplotlib.pyplot as plt