2013-03-07 32 views
5

Tôi có một tập lệnh bên dưới sử dụng Thor để chạy như một công việc cào quản lý ARGV.Làm thế nào để giết tất cả các quá trình bên trong ruby ​​Thor dừng lại?

#!/usr/bin/env ruby 
require "thor" 

class Run < Thor 

    desc "start", "start script" 
    def start 
     p1 = fork{ loop... } 
     p2 = fork{ loop... } 

     # 3 processes running 

     Process.detach(p1) 
     Process.waitpid(p1) 

    end 

    desc "stop", "stop script"  
    def stop 
    # kill all 3 pids 
    end 

end 

Run.start 

Khi bắt đầu ruby script.rb start, nó tạo ra hai quy trình con (tổng cộng ba). Câu hỏi của tôi là làm thế nào để giết tất cả các quá trình khi tôi thực hiện ruby script.rb stop. Tôi đã nhìn thấy trên web rằng, khi bắt đầu, tôi nên lưu trữ quá trình cha mẹ pid vào một tập tin và, khi dừng lại, tôi đọc nó và giết. Vấn đề là giết cha mẹ không giết bọn trẻ. Vì vậy, tôi có thể lưu tất cả ba pids trong tập tin và giết từng cái một.

Tôi tự hỏi mình là cách phù hợp để thực hiện việc này là gì và liệu cách tôi đang làm việc với các quy trình bên trong start là chính xác hay không.

+2

Lưu trữ các PID trên hệ thống tập tin có vẻ là một thực tế khá phổ biến của các dịch vụ daemonized, trong trường hợp của bạn nó âm thanh như lưu trữ tất cả các PID trên hệ thống tập tin có ý nghĩa, đó là cách chắc chắn nhất để giết các quy trình chính xác. –

+0

cảm ơn câu trả lời của bạn! – Luccas

+0

Một giải pháp thay thế có thể sẽ là đính kèm một finalizer khi đối tượng được GC'd mà sẽ làm sạch đúng cách sau khi chính nó. http://stackoverflow.com/questions/5956067/ruby-destructors Bạn cũng có thể sử dụng đá quý Daemons để quản lý các quy trình. http://daemons.rubyforge.org/ –

Trả lời

0

Nếu bạn biết pid cha mẹ của bạn, bạn có thể tìm và tiêu diệt tất cả những đứa trẻ như thế này:

# Find child pids, works on Linux/OSX 
def child_pids(pid) 
    pipe = IO.popen("ps -ef | grep #{pid}") 
    pipe.readlines.map do |line| 
    parts = line.strip.split(/\s+/) 
    parts[1].to_i if parts[2] == pid.to_s and parts[1] != pipe.pid.to_s 
    end.compact 
end 

# kill -9 every child 
child_pids(parent_pid).each { |pid| Process.kill('TERM', pid) } 
Các vấn đề liên quan