Python 应用程序因“PyEval_RestoreThread:必须在持有 GIL 的情况下调用该函数,但 GIL 已释放”而崩溃

Posted

技术标签:

【中文标题】Python 应用程序因“PyEval_RestoreThread:必须在持有 GIL 的情况下调用该函数,但 GIL 已释放”而崩溃【英文标题】:Python app crashed with "PyEval_RestoreThread: the function must be called with the GIL held, but the GIL is released" 【发布时间】:2021-06-21 23:55:19 【问题描述】:

我有一个 Python 程序,由于它太大,这里是它的源代码链接: Link

当我在 Mac 上运行它时,有时会出现这个奇怪的异常:

Fatal Python error: PyEval_RestoreThread: the function must be called with the GIL held, but the GIL is released (the current Python thread state is NULL)
Python runtime state: initialized

Current thread 0x0000000115f8ce00 (most recent call first):
  File "/usr/local/Cellar/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/__init__.py", line 1429 in mainloop
  File ".../PyPlusSource/pyplus.py", line 1435 in <module>

那么为什么会这样呢?请用简单的话解释一下。感谢您的任何想法!

编辑: 我在 MacOS 11.2.3 Big Sur [Not beta] 上,安装了 Python 3.9.2 [Not beta again]。而且这个错误很难重现

【问题讨论】:

哇,我没见过这样的东西。我认为错误发生在全局解释器锁有问题的 python 解释器中。你用的是什么python版本?你运行的是什么操作系统? 您导入了一个名为 pygson 的模块。那是什么?我在 PyPi 上找不到它。 打开任务管理器,查看进程占用的内存。如果增加很多,可能是内存问题。 您介意为我们分享一个minimal reproducible example,这样我们就不需要猜测您可能做了什么? 你究竟做了什么来得到这个错误?我让它运行了,没有遇到任何错误 【参考方案1】:

一般来说,这应该只发生在将 Python 与其他语言(通常是 C;参见,例如,When the GIL is released?)的组件相结合的代码中。

根据您的描述,不清楚您的代码的哪一部分导致错误(11 天前提出的原始问题说它是line 1435,您 6 天前添加的视频显示它是line 1452,以及 GitHub 上的 PyPlus 代码您指的是 2 天前更改,目前只有 1441 行),因此,您需要检查自己在代码中的确切位置产生了错误。

该错误进一步涉及tkinter/__init__.py 中的第 1429 行(据我所知,在我的 Python 3.9 版本的tkinter 中)是以下函数中的if string:

def _getints(self, string):
    """Internal function."""
    if string:
        return tuple(map(self.tk.getint, self.tk.splitlist(string)))

所以,看来函数是用未定义的变量string调用的。

由于各种原因,我多次收到此PyEval_RestoreThread 错误:

当来自 cythonized Python 模块(Mac 上为.so)的函数调用来自另一个模块的函数时,间接导入。例如,如果模块a.py 导入b.pyb.py 导入c.py,并且a.py 中的函数使用来自c.py 的函数。当从 PyCharm 或通过python3 myprogram.py 从终端运行时,没有错误,但一旦模块被 cythonized,a.so 中的函数就无法找到 c.so 中的函数,我收到此错误。

关于辅助线程中未捕获的异常;例如,当我没有检查从文件中读取的变量的类型并试图在我的(PySimpleGUI = tkinter-based)GUI 中更新一个字符串,其值不是字符串。

【讨论】:

以上是关于Python 应用程序因“PyEval_RestoreThread:必须在持有 GIL 的情况下调用该函数,但 GIL 已释放”而崩溃的主要内容,如果未能解决你的问题,请参考以下文章

使用 python 线程时,python 因核心转储而崩溃

Python 7Zip 错误因扫描警告而失败

卷曲工作,但 python 请求因 SSLError 而失败

python import dlib 因分段错误而失败

Kiwi备份恢复因python错误而失败

程序员自己写 Bug:因拼写错误,PyPI 多个软件包含后门!