我正在尝试解决以下问题:假设我有一个Python脚本(我们称之为Test.py),它使用C ++扩展模块(通过SWIG制作,让我们调用模块“Example”)。我在同一目录中有Test.py,Example.py和_Example.so。
现在,在运行Test.py的过程中,我想对我的Example模块进行更改,重新编译(将覆盖现有的.so),并使用命令优雅地停止仍在使用的Test.py旧版本的模块(Test.py有一些清理工作,它使用了一些在Example模块中定义的东西),然后使用新版本的模块重新启动它。优雅地停止Test.py然后重新编译模块在我的情况下不是一个选项。
问题是,只要_Example.so被覆盖并且Test.py尝试访问Example模块中定义的任何内容(正常停止时),我就会遇到分段错误。对此的一个解决方案是通过在末尾附加版本号来明确命名Example模块,但我想知道是否有更好的解决方案(我不想导入Example_1_0)?
答案 0 :(得分:2)
您可以在启动Test.py时将Example。*文件复制到该实例唯一的临时文件夹(查看 tempfile.mkdtemp ,它可以创建安全,唯一的文件夹) ,将其添加到 sys.path ,然后导入Example;在Test.py关机中,在清理阶段删除该文件夹( shutils.rmtree )。
这意味着Test.py的每个实例都将在其自己的Example模块副本上运行,而不会干扰其他模块,并且只有在重新启动时才会更新为新的。
您需要示例。*文件与Test.py不在同一文件夹中,否则导入将首先获得这些文件。只需将它们存储在子文件夹中即可。
答案 1 :(得分:0)
您可以编译为临时名称(Example_1_0),但只要Test.py停止,请重命名为_Example.so并然后重新启动Test.py。
编辑:
由于您正在运行多个实例,因此您可以考虑使用某种类型的 stack / generator / symlink 线程将它们全部链接在一起,以便在_Example.so上执行您自己的“垃圾回收”:< / p>
您可以运行主测试器脚本,使用子进程启动Test.py脚本。每个Test.py都可以将_ExampleXXX.so作为命令行参数。然后保留每个.so文件的引用计数 - 当引用计数降为零时,该模块的版本将被删除,并使用最新版本的_Example.so重新生成该进程。
这可能有点棘手,但您可能只能使用
while True:
#Do stuff
for p in myprocesses:
retcode = p.poll() # Set to [None][1] if the process hasn't finished
# Do something with the return code
或类似的逻辑。