使用Python的subprocess.Popen()启动Java程序时,为什么子进程打开的数据库连接未关闭?

0 投票
2 回答
1132 浏览
提问于 2025-04-16 02:44

我们使用Robot Framework来进行测试自动化,我们的jython测试代码通过subprocess.Popen()来启动一个java子进程。

    cmd = "java -jar program.jar"
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    process.wait()

这段Java代码使用JDBC连接到Oracle数据库,并且同一个程序需要连续执行好几次。

我们遇到的问题是,当Java程序结束后,连接到Oracle数据库的连接没有被关闭——这样连续执行几次后,测试就开始失败,因为Oracle不再接受更多的连接。

通过netstat命令可以看到,连接到Oracle的那些旧的TCP连接是由jython的进程ID(也就是父进程)拥有的。

那么,为什么当Java程序(也就是子进程)结束时,这些连接没有被关闭呢?

2 个回答

1

可以考虑使用 os.kill 这个方法(在 2.6 及以上版本中,process.terminate 就是用的这个)。

如果这个方法不管用,考虑到你这个比较特殊的设置——一个 JVM 调用另一个 JVM,这种情况通常不需要——你可能想用 execnet 这个工具(http://codespeak.net/execnet/)来启动一个 CPython 进程来控制它。CPython 在访问主机操作系统服务方面的功能比我们在 Jython 中提供的要强大得多。使用 execnet 是个不错的办法,可以把这些优点结合起来。

2

我不太确定,但有可能是因为你在用Jython,所以解释器掌控了连接(这样连接就会一直存在,直到那个进程结束)。你有没有试过在process.wait()之后使用process.terminate()呢?

撰写回答