【问题标题】:When to use cleanup() in Jython何时在 Jython 中使用 cleanup()
【发布时间】:2020-08-22 15:44:54
【问题描述】:

每次在 Jython 中的 PythonInterpreter 中是否需要在 close() 之前调用 cleanup()

我一直在阅读文档,但我没有找到有关此功能的太多信息。 javadocs 什么都不说。我找到的最接近的信息是here, in readthedocs,他们解释说在某些使用线程编程的情况下需要进行清理,我什至不确定他们是否引用了这个特定的函数。

我想知道什么时候需要打电话给cleanup()...,如果答案总是这样,那他们为什么要让cleanup()close() 分开函数呢?

【问题讨论】:

标签: java jython scripting-language jython-2.7


【解决方案1】:

好的,我一直在阅读 Jython 源代码并进行了一些测试。这是我发现的:

cleanup() 的作用:它负责未处理的资源,例如正在运行的线程和文件。

cleanup() 没有什么:以任何形式重置解释器的状态;保留导入的模块和定义的变量。

以下示例显示了这种行为:

示例 1

让我们导入一个模块,定义一个变量并打开一个文件。

PythonInterpreter py = new PythonInterpreter();

String code1 = "import sys;"
        + "a=45;"
        + "f = open('test.txt')";
String code2 = "print(sys.version_info);"
        + "print(a);"
        + "print(f.closed)";

// first execution
py.exec(code1);
py.exec(code2);

// second execution
py.cleanup();
py.exec(code2);

py.close()

输出

sys.version_info(major=2, minor=7, micro=2, releaselevel='final', serial=0)
45
False
------
sys.version_info(major=2, minor=7, micro=2, releaselevel='final', serial=0)
45
True

模块sys和变量af在清理后仍然存在相同的值,但是打开的文件被关闭了。

示例 2

为此,func 是一个慢速函数,大约需要 2 秒才能完成(比普通的 cleanup() 多)。

PythonInterpreter py = new PythonInterpreter();

String code3 = "from threading import Thread\n"
        + "def func():\n"
        + "  print 'th start'\n"
        + "  for i in range(0,20000000):\n"
        + "    x=i\n"
        + "  print 'th done'\n"
        + "th = Thread(target=func)\n"
        + "th.start()";
String code4 = "print th.isAlive()\n"
        + "th.join()";

// first execution
py.exec(code3);
py.exec(code4);
System.out.println("------");   

// second execution
py.exec(code3);
py.cleanup();
py.exec(code4);

py.close();

输出:

th start
True
th done
------
th start
th done
False

在第一次执行中,主线程有足够的时间检查th是否存活并打印出来。在第二个中,它总是等待th 完成,这意味着cleanup() 在某个地方加入了线程。

结论

正如@mzjn 所指出的,close() 函数调用cleanup(),这是有道理的,所以您永远不需要在close() 之前调用cleanup()。唯一需要手动调用它的情况是,如果您想继续使用 PythonInterpreter 但需要关闭所有打开的文件并加入所有线程。

【讨论】:

  • 感谢您提供详细信息。如果我有口译员听取所有即将到来的interpreter.exec()interpreter.eval() 请求怎么办?我需要定期手动拨打cleanup()吗?我正在进行负载测试,我可以看到相同的 python 代码,执行时间变得越来越慢。并且经过一段时间后,执行时间越来越好,然后又变慢了。但我可以看到整体执行时间越来越长。我在想cleanup() 是否有帮助?
  • 据我所知,如果您在代码中正确管理文件和线程(分别关闭和加入它们),则没有必要。
  • 我不是在管理文件,只是在初始化实例并调用方法。据我了解基于 Jython 文档,我可以直接使用解释器自己的线程管理来处理即将到来的 evalexec 调用(因为解释器是线程安全的):我有一个池来控制多少当前正在处理请求,但它们都使用相同的解释器。在您回复之前,我尝试过定期调用cleanup(),似乎内存消耗更稳定,执行时间也更稳定。但我可能需要更多的负载测试,看看它是否真的有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
相关资源
最近更新 更多