在Jython中何时使用cleanup()函数

huangapple go评论72阅读模式
英文:

When to use cleanup() in Jython

问题

在Jython中的PythonInterpreter中,每次在调用close()之前是否有必要调用cleanup()吗?

我一直在阅读文档,但关于这个函数的信息很少。javadocs中根本没有提到。我找到的最接近的信息是在这里,在readthedocs上,他们解释说在某些情况下在使用线程进行编程时需要进行清理,我甚至不确定他们是否指的是这个特定的函数。

我想知道什么情况下我需要调用cleanup()... 如果答案总是需要,那为什么会将cleanup()close() 设计成不同的函数呢?

英文:

Is it necessary to call cleanup() before close() in a PythonInterpreter in Jython every time?

I've been reading the docs, but I don't find much information about this function. The javadocs don't say anything at all. The closest information I've found is here, in readthedocs, where they explain that a cleanup is necessary in some cases programming with threads, and I'm not even sure they refer to this particular function.

I wonder when I need to call cleanup()... and if the answer is always, then why would they make cleanup() and close() separate functions?

答案1

得分: 1

好的,以下是您要翻译的内容:

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)";

// 第一次执行
py.exec(code1);
py.exec(code2);

// 第二次执行
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()";

// 第一次执行
py.exec(code3);
py.exec(code4);
System.out.println("------");	

// 第二次执行
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(),这是有道理的,因此您在关闭之前从不需要调用 cleanup()。唯一需要手动调用它的情况是,如果您希望继续使用 PythonInterpreter 但需要关闭所有打开的文件并加入所有线程。

英文:

Okay, I've been reading the Jython source code and doing some tests. Here is what I found:

What cleanup() does: It takes charge of the unhandeled resources, like running threads and files.

What cleanup() doesn't: Reset the state of the interpreter in any form; imported modules and defined variables are kept.

The following examples show this behavior:

Example 1

Let's import a module, define a variable and open a file.

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()

It outputs

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

The module sys and the variables a and f still exist with the same values after the cleanup, but the open file is closed.

Example 2

For this, func is a slow function that takes aprox 2 seconds to complete (more than a normal 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();

That outputs:

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

In the first execution, the main thread has plenty of time to check if th is alive and print it. In the second one, it always waits for th to finish, meaning that the cleanup() joins the thread somewhere.

Conclusion

As @mzjn pointed out, the close() function calls cleanup() and that makes sense, so you never need to call cleanup() before close(). The only case where you could need to call it manually would be if you wanted to continue using the PythonInterpreter but needed to close all open files and join all threads.

huangapple
  • 本文由 发表于 2020年8月22日 23:44:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/63538087.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定