Ruby 我怎样才能终止进程,它已经使用system()生成了一个子进程?
我在Windows7上使用Cygwin(尽管同样的问题可能也适用于本机Linux环境) 父进程(碰巧是一个Ruby程序,但如果这是一个纯C应用程序)使用Ruby 我怎样才能终止进程,它已经使用system()生成了一个子进程?,ruby,linux,windows,process,cygwin,Ruby,Linux,Windows,Process,Cygwin,我在Windows7上使用Cygwin(尽管同样的问题可能也适用于本机Linux环境) 父进程(碰巧是一个Ruby程序,但如果这是一个纯C应用程序)使用system()执行外部(可能是长时间运行的)命令 当此外部程序正在运行时,父进程将被终止。子进程仍处于活动状态。我可以做些什么来确保子进程也被杀死 这里有一个“沙箱”场景来解释问题:在一个终端窗口中,我执行以下命令: ruby -e 'puts $$; system("sh")' # Could also be a C program 显然,
system()
执行外部(可能是长时间运行的)命令
当此外部程序正在运行时,父进程将被终止。子进程仍处于活动状态。我可以做些什么来确保子进程也被杀死
这里有一个“沙箱”场景来解释问题:在一个终端窗口中,我执行以下命令:
ruby -e 'puts $$; system("sh")' # Could also be a C program
显然,在打印了进程id之后,sh
命令将永远挂起此消息
现在我尝试从另一个终端窗口
kill -INT ...
杀死Ruby进程。使用procps或ps,我可以验证此进程是否仍然有效。现在我用
kill -TERM ....
尽管如此,这个过程并没有被扼杀。最后我做了一个测试
kill -KILL ....
当然,这就是工作。Ruby进程已被终止,但子进程('sh')仍处于活动状态
我知道这是预期的行为,但什么是简单可靠的解决方法
在执行system
之前,我试图建立一个会话并调用了Process.setsid
,但收到了错误消息
`setsid':不允许操作(Errno::EPERM)
可能Cygwin上没有setsid
,这不会让我感到惊讶,因为Windows进程处理非常不同
还有其他想法吗,我可以试试吗?顺便说一句,代码最终应该移植到Linux,所以如果可能的话,我想使用一个在Cygwin和Linux下运行的解决方案。看看关于Ruby异步处理的奇妙博客,它建议在Linux中使用fork,在Windows中使用spawn,我建议在Cygwin中尝试这两种方法
pid = fork do
exec 'sleep', '10'
end
Process.kill pid
你试过killall-9Ruby吗?天哪!这会杀死我所有的Ruby进程!!!这两种方法都不能解决我的问题(因为它只会杀死父进程而不是它的子进程,而且还会杀死从Cygwin外壳派生的所有其他Ruby进程!Windows中的通用解决方案是将子进程放入作业对象中。我不知道您是否可以通过Ruby/Cygwin明智地做到这一点……问题是,作业对象解决方案将在多大程度上运行在Linux上。它听起来不是很可移植。我正在考虑这个问题。使用这种方法,我必须将子进程的进程id(在您的示例中为变量pid)存储在某个地方,以便killer进程可以获取它。我只是希望有一种解决方案,我可以使用
system
来派生子进程,这是可能的。。。