如何在ruby中控制(启动/终止)后台进程(服务器应用程序)

我正在尝试通过ruby为集成测试(实际规格)设置一个服务器,但无法弄清楚如何控制该过程。

所以,我想要做的是:

  1. 为我的gem执行rake任务,执行集成规范
  2. 任务需要首先启动服务器(我使用webrick),然后运行规范
  3. 在执行规范后它应该杀死webrick所以我没有留下一些未使用的后台进程

webrick不是必需的,但它包含在ruby标准库中,因此能够使用它会很棒。

希望有人能够提供帮助!

PS。 我正在linux上运行,因此将这项工作用于Windows并不是我的主要优先事项(现在)。

标准方法是使用系统函数fork(复制当前进程),exec(用可执行文件替换当前进程)和kill(向进程发送信号以终止它)。

例如 :

pid = fork do # this code is run in the child process # you can do anything here, like changing current directory or reopening STDOUT exec "/path/to/executable" end # this code is run in the parent process # do your stuffs # kill it (other signals than TERM may be used, depending on the program you want # to kill. The signal KILL will always work but the process won't be allowed # to cleanup anything) Process.kill "TERM", pid # you have to wait for its termination, otherwise it will become a zombie process # (or you can use Process.detach) Process.wait pid 

这适用于任何类Unix系统。 Windows以不同的方式创建进程。

我只需要做类似的事情,这就是我想出的。 @Michael Witrant的回答让我开始,但我改变了一些事情,比如使用Process.spawn而不是fork( 更新更好 )。

 # start spawns a process and returns the pid of the process def start(exe) puts "Starting #{exe}" pid = spawn(exe) # need to detach to avoid daemon processes: http://www.ruby-doc.org/core-2.1.3/Process.html#method-c-detach Process.detach(pid) return pid end # This will kill off all the programs we started def killall(pids) pids.each do |pid| puts "Killing #{pid}" # kill it (other signals than TERM may be used, depending on the program you want # to kill. The signal KILL will always work but the process won't be allowed # to cleanup anything) begin Process.kill "TERM", pid # you have to wait for its termination, otherwise it will become a zombie process # (or you can use Process.detach) Process.wait pid rescue => ex puts "ERROR: Couldn't kill #{pid}. #{ex.class}=#{ex.message}" end end end # Now we can start processes and keep the pids for killing them later pids = [] pids << start('./someprogram') # Do whatever you want here, run your tests, etc. # When you're done, be sure to kill of the processes you spawned killall(pids) 

这就是她写的所有内容,试试看,让我知道它是如何运作的。

我尝试过fork,但是当ActiveRecord参与这两个进程时,它会遇到一些问题。 我建议使用Spawn插件( http://github.com/tra/spawn )。 它只做fork,但负责ActiveRecord。