如何停止 Python 运行 Py4J ClientServer

Posted

技术标签:

【中文标题】如何停止 Python 运行 Py4J ClientServer【英文标题】:How do stop Python running Py4J ClientServer 【发布时间】:2019-10-13 23:48:35 【问题描述】:

我有一个 Java main() 正在启动一个或多个 Py4J ClientServer 和 python 实例以连接回 ClientServer(都使用不同的端口集)。这是可行的,但是当 main 完成时,Java 和 python 实例都没有退出

我正在按如下方式启动 ClientServer:

clientServer = new ClientServer(javaPort, GatewayServer.defaultAddress(), pythonPort,
    GatewayServer.defaultAddress(), GatewayServer.DEFAULT_CONNECT_TIMEOUT,
    GatewayServer.DEFAULT_READ_TIMEOUT, ServerSocketFactory.getDefault(), 
    SocketFactory.getDefault(), jep); 

通过传入两个端口并执行以下操作来启动python:

python_classifier.gateway = ClientServer(
    java_parameters=JavaParameters(port=javaPort, auto_convert=True, auto_close=True),
    python_parameters=PythonParameters(port=pythonPort, daemonize=False,
         daemonize_connections=True),
    python_server_entry_point=python_classifier)

我尝试设置 deamonize=True,但随后连接开始失败。我还添加了一个 Java 关闭挂钩来尝试杀死我已经启动的 python 进程,但它并不总是被调用。

那么,关于如何在 Java 端退出时让 python 安静退出的任何想法?

【问题讨论】:

查看finally 块是否有效。 两者都是报告的问题。 Java -> github.com/bartdag/py4j/issues/302。 Python -> github.com/bartdag/py4j/issues/148 【参考方案1】:

我有很多关于管理从 Java 开始的 python 进程的代码,包括 shutdownHooks、finalizers() 和超时使用监听器。主要问题原来是对于给定的 ClientServer/Process 对,我在调用 Process.destroyForcibly() 之前调用 ClientServer.shutdown() 在交换顺序并首先终止进程之后,shutdown() 不再挂在 close( )(见下文)。

Py4J java 代码中有一条关于如果套接字没有先关闭,readLine() 中的阅读器挂起的注释。尽管首先关闭了此套接字,但它似乎仍然挂起。下面的堆栈跟踪来自 Finalizer 线程,但我也在自己的线程中得到了这个。

【讨论】:

以上是关于如何停止 Python 运行 Py4J ClientServer的主要内容,如果未能解决你的问题,请参考以下文章

Java InputStream 到 Python (PY4J)

如果 py4j JVM 正在运行,那么在 python 中进行测试的最佳方法是啥?

如何使用 PY4J 从 python 调用 java

py4j:如何从 Python 启动 java 网关

如何在 py4j 中将 Java 列表转换为 Python 列表

py4j - 我将如何在 java 中调用 python 方法