使用Python的subprocess.Popen()启动Java程序时,为什么子进程打开的数据库连接未关闭?
我们使用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()
呢?