我正在开发一个Ruby on Rails应用程序。 部分function是通过串口启动和closures与Modbus从站的连接,获取数据并将其存储到数据库中。 另外我做了一个python脚本,正是我所需要的,所以我不想重新发明轮子并将其重写到Ruby中。
我的想法是启动一个进程,它将执行python脚本,并在不需要的时候终止进程。
我开始这个过程如下,所以我可以访问它的PID:
def start ... @@pids[ object.id ] = IO.popen("python ./python_script_name.py").pid ...
@@ pids是一个散列,它将所有已启动的进程的pid以key的forms存储为object.id(假设每个对象只能启动一个进程)
当我想closures连接时,我杀死了这个进程:
def stop ... pid = @@pids[ object.id ] system("kill #{pid}")
这导致僵尸进程( ps aux | grep python
后可见):
[python] <defunct>
我试图发送SIGCHLD
信号到rails应用程序(因为它是以前称为python脚本的父),但它不起作用。
我想补充一点,我可能需要经常调用/终止这个过程,这样会导致大量的僵尸进程。
如何在不离开僵尸进程的情况下杀死一个进程?
问题不在python脚本中 – 信号默认处理正确(在实现signal
模块后没有改变)。
这个问题是在红宝石脚本。 杀死一个进程后,其父(在这种情况下的轨道服务器)需要知道它被杀死。 为此目的有一个wait
功能。 从ruby文档:
父进程应该使用Process.wait来收集其子进程的终止状态
所以要正确处理杀死一个孩子的过程需要遵循:
def stop ... pid = @@pids[ object.id ] Process.kill( 15, pid ) Process.wait( pid ) ...