在Python中加载两个动态库实例

时间:2019-03-23 10:11:22

标签: python ctypes python-multiprocessing python-multithreading

我有一个用Fortran编写并作为动态库编译(带有-fPIC)的程序。我在Python中加载了CDLL以执行一些数值计算。该库使用内部持久性存储器(在模块中)保存中间值。我在Windows和Linux上都工作(分别使用.dll和.so)。动态库打包在Python模块中,并安装在lib子目录中。

如果我运行两个不同的Python脚本,它们在同一台计算机上加载了动态库,它们会获得单独的内部内存还是会访问同一内存(从而破坏结果)?

如果我这样做会如何影响

  • 将它们加载到另一个多处理实例中
  • 将它们加载到不同的多线程实例中
  • 将它们加载到两个具有不同内核的Jupyter笔记本中
  • 在不同的Python虚拟环境中运行它们

有一个similar question。但是,由于动态库包含在Python模块中,因此我想避免不得不重命名文件和在文件中四处移动。

1 个答案:

答案 0 :(得分:1)

  

如果我运行两个不同的Python脚本,它们在同一台计算机上加载了动态库,它们会获得单独的内部内存还是会访问同一内存(从而破坏结果)?

  • 同一库只能一次加载;更准确地说,只要您尝试使用相同的路径加载库,则在此过程中它只会加载一次。

    • 现在假设您加载了一个库,将该库复制/粘贴到其他位置,将其重命名并尝试加载该副本,然后将其加载两次。
  • 对于多次加载同一库所使用的内存,由于仅加载一个库,因此没有损坏。如果您加载它的副本,那么这些库中的每个库都会获得自己的内存分配。

  

将它们加载到另一个多处理实例中

没问题。多重处理使用不同的进程,并且不同的进程无法将任何内容覆盖到另一个进程地址空间中(除非明确要求)。

  

将它们加载到不同的多线程实例中

您将只能加载该库的一个实例。话虽这么说,因为您只有一个库实例,从技术上来说并且取决于库,对函数的调用可能会覆盖库的先前内部状态。在很大程度上取决于该库是否可以在多线程上下文中使用。

正如您所说的,库保留一个内部状态,对函数的每次调用都有机会覆盖/更改先前的内部状态(取决于被调用函数对内部状态的影响)。

  

将它们加载到两个具有不同内核的Jupyter笔记本中

取决于两个笔记本是否正在使用两个不同的解释器实例。

  • 如果同一解释器运行两个笔记本,则解释器只会加载一个库实例。

  • 不同的解释器:两个进程->两个具有各自独立状态的库。

  

在不同的Python虚拟环境中运行它们

不同的虚拟环境使用不同的进程。