扩展中的致命错误:PyThreadState_Get:在 Mac 上使用 SWIG 和 Anaconda3 时没有当前线程

Posted

技术标签:

【中文标题】扩展中的致命错误:PyThreadState_Get:在 Mac 上使用 SWIG 和 Anaconda3 时没有当前线程【英文标题】:Fatal error in extension: PyThreadState_Get: no current thread when using SWIG with Anaconda3 on a Mac 【发布时间】:2018-01-16 21:08:12 【问题描述】:

我只在 Mac 上使用 anaconda3 和 swig 时遇到此错误。有人对如何解决这个问题有任何建议吗?

这是test.i 文件。

# test.i
%module test

%
int hello();
%

这是test.c 文件。

//test.c
#include <stdio.h>

int hello() 

    printf("Hello\n");
    return 0;


这是创建扩展的编译步骤。

$ swig -python test.i
$ cc -c $(python3-config  --cflags) test.c test_wrap.c
$ cc -bundle -L/Users/$USER/miniconda3/lib/python3.6/config-3.6m-darwin -lpython3.6m -ldl test.o test_wrap.o -o _test.so

$ python test.py
Fatal Python error: PyThreadState_Get: no current thread

[1]    97445 abort      python test.py

同样,任何其他操作系统都没有错误。他们相应的步骤起作用。它适用于 Homebrew Python2,也适用于 Homebrew Python3。它也适用于 Anaconda2。但它不适用于 Anaconda3 或 Anaconda3 环境。

请参阅下面的最小工作示例。

https://github.com/kdheepak/mwe-swig-python3-anaconda

【问题讨论】:

【参考方案1】:

问题可能是您尝试链接 python3.6 库,而 python 可执行文件已经链接了 python 库。

尝试执行与 setup.py 相同的操作(这适用于您的 github 示例):

#!/usr/bin/env python
from distutils.core import setup, Extension
test_module = Extension('_test', sources=['test_wrap.c', 'test.c'],)
setup (name = 'test', version = '0.1', ext_modules = [test_module], py_modules = ["test"],)

您将看到这会创建一个使用 -undefined dynamic_lookup 的链接命令,而无需显式链接到 python3.6m 或 ld 库。

【讨论】:

感谢您的回答。更改 cmake 文件以使用未定义的动态查找修复了此问题。你能告诉我你是怎么知道这就是 distutils 所做的吗? 如果您只是运行 setup.py 脚本(尝试构建或安装扩展),那么您应该会在终端中看到编译和链接命令。 我明白了。我使用了pip install -e .,但在尝试时没有看到该命令。【参考方案2】:

python3-config --cflags 不应在为 Python 创建扩展模块时使用,也不应始终链接到 Python 库。相反,您应该查询 Python 本身(特别是 distutils sysconfig 模块)以获取适当的值。

应通过以下方式查询编译器标志: python -c "from distutils import sysconfig; print(sysconfig.get_config_vars('CFLAGS'))"

应通过以下方式查询链接器标志: python -c "from distutils import sysconfig; print(sysconfig.get_config_var('BLDSHARED').split(' ', 1)[1])"

【讨论】:

感谢您的回答。此时,我只是使用-undefined dynamic_lookup 来解决这个问题。你会推荐你的方法吗? -undefined dynamic_lookup 不是解决这个问题的方法,不。这只防止(静态)链接器(ld64)抱怨缺少符号。这里的问题是,有两个提供程序(python 可执行文件和libpython.dylib 共享库)具有相同的符号(PyThreadState_Get),并且调用来自 dylib 的一个而不是来自可执行文件的一个,而不是它根本不应该加载。 我已经详细说明了如何解决这个问题。您只需要停止传递 -lpython3.6m 而是询问 Python 本身的链接器标志应该是什么。 啊,谢谢。我正在用手机回复,并没有意识到这是线程的一部分。我会试试你的方法,看看是否有效。

以上是关于扩展中的致命错误:PyThreadState_Get:在 Mac 上使用 SWIG 和 Anaconda3 时没有当前线程的主要内容,如果未能解决你的问题,请参考以下文章

未找到安装了扩展 php_com_dotnet 的致命错误类 COM

无法解决 http 请求致命错误

“发生致命的Javascript错误。你想发一个错误报告吗?“

致命错误:ext/standard/php_smart_str.h:没有那个文件或目录

Facebook 需要 CURL PHP 扩展错误

致命错误:找不到“Redis”类