gpt4 book ai didi

java - 如何从 java 运行多线程 python 脚本?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:00:55 28 4
gpt4 key购买 nike

我正在用 Java 构建一个框架,它将监听事件,然后在 Jython 中处理它们。不同的事件类型将发送到不同的脚本。

由于在调用 PythonInterpreter.exec() 时 jython 需要相当长的时间来编译脚本,因此我将不得不预编译脚本。我正在按照以下方式进行操作:

// initialize the script as string (would load it from file in final version)
String script = "print 'foo'";
// get the compiled code object
PyCode compiled = org.python.core.__builtin__.compile( script, "<>", "exec" );

PyCode 编译的对象将被推送到存储库并在事件到来时使用

PythonInterpreter pi = new PythonInterpreter();
pi.set( "variable_1", "value_1");
pi.set( "variable_x", "value_x");
pi.exec( compiled );

现在是我的难题 - 可能同时发生多个特定类型的事件 - 因此多个脚本实例同时运行。

几乎所有脚本都可能会保持短暂的生命周期 - 最多 100 行,没有循环。数量和频率是完全随机的(用户生成的事件),每种事件类型可能在每秒 0 到大约 200 次之间。

最好的方法是什么?我正在考虑几种可能性:

  1. 在触发事件点使用同步 - 这将防止同一脚本的多个实例,但事件也不会像应有的那样快速处理
  2. 创建一个相同类型的脚本池,通过克隆原始 PyCode 对象以某种方式填充 - 最大的问题可能是优化池大小
  3. 在需要时动态地从父级克隆脚本对象,然后在 exec() 完成时丢弃它 - 这样可以从编译中消除延迟,但它仍然存在于克隆方法中

可能数字 2 和 3 的组合是最好的 - 创建动态池大小?

那么,有什么想法吗? ;)

最佳答案

遗憾的是 PyCode 实例不是不可变的(类中有很多公共(public)成员)。

您可以使用此代码预编译可重用的脚本:

// TODO: generate this name
final String name = "X";
byte[] scriptBytes = PyString.to_bytes(script);
CompilerFlags flags = Py.getCompilerFlags();
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
Module.compile(parser.parse(new ByteArrayInputStream(scriptBytes), "exec",
"<>", flags), ostream, name, "<>", false, false, false, flags);
byte[] buffer = ostream.toByteArray();
Class<PyRunnable> clazz = BytecodeLoader.makeClass(name, null, buffer);
final Constructor<PyRunnable> constructor = clazz
.getConstructor(new Class[] { String.class });

然后,您可以在需要时使用构造函数为脚本生成 PyCode 实例:

 PyRunnable r = constructor.newInstance(name);
PyCode pc = r.getMain();

我会是第一个承认这不是做事的好方法的人,并且可能充分说明我对 Jython 缺乏经验。但是,它比每次都编译要快得多。该代码在 Jython 2.2.1 下运行,但无法在 Jython 2.5 下编译(您的也不会)。

关于java - 如何从 java 运行多线程 python 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1260864/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com