首页 > 解决方案 > 如何停止 Python 运行 Py4J ClientServer

问题描述

我有一个 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 安静退出的任何想法?

标签: javapy4j

解决方案


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

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

在此处输入图像描述


推荐阅读