如何防止动态库的多次初始化

时间:2013-05-20 15:07:04

标签: python c openssl initialization python-import

我正在使用Python 2.7版。 我有一个用C编写的Python模块扩展。 模块初始化函数PyMODINIT_FUNC initmymodule包含一些用于初始化OpenSSL库的代码。我的模块构建为共享库并通过imp.load_dynamic

加载

此模块可能会多次加载,我无法控制它。 Django和python这样做。当它加载两次,然后OPENSSL_config函数调用两次。它导致流程崩溃。

我无法用C代码控制它,我无法用Python代码控制它。

这里看一下文档 http://docs.python.org/2.7/library/imp.html 它说:

  

imp.load_dynamic加载并初始化一个实现为的模块   动态加载共享库并返回其模块对象。 如果   该模块已初始化,将再次初始化

尼斯。

我发现在Python 3.4版中解决了类似的问题 http://hg.python.org/cpython/file/ad51ed93377c/Python/import.c#l459

  

支持多次初始化的模块设置了他们的m_size   字段为非负数(表示字母的大小)   模块特定的状态)。它们仍然记录在扩展中   字典,以避免两次加载共享库。

但是我应该在Python 2.7中做些什么?

2 个答案:

答案 0 :(得分:3)

也许通过注册自己的自定义导入钩子来解决方法,您可以控制导致问题的情况(防止双重初始化)。编写自定义导入钩子的一些参考:

  • Python导入挂钩article
  • PEP-302新的导入钩子 - python 2.3 +
  • 创建并注册自定义导入/重新加载功能 - 项目lazy_reload
  • 中的实施示例

这是 hackish 解决方案,因此如果要在生产系统中使用,我建议格外小心。

答案 1 :(得分:0)

我找到了问题的原因。这是因为我的django应用程序使用驱动程序连接PostgreSQL,这个驱动程序加载OpenSSL库。它会导致冲突,就像user315052

comment所示

我认为我必须将我的应用程序的所有加密功能都移到单独的进程中。