Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 我怎样才能终止进程,它已经使用system()生成了一个子进程?_Ruby_Linux_Windows_Process_Cygwin - Fatal编程技术网

Ruby 我怎样才能终止进程,它已经使用system()生成了一个子进程?

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 显然,

我在Windows7上使用Cygwin(尽管同样的问题可能也适用于本机Linux环境)

父进程(碰巧是一个Ruby程序,但如果这是一个纯C应用程序)使用
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
来派生子进程,这是可能的。。。