2012-04-18 53 views
8

tôi đang học lập trình hệ thống thông qua ruby ​​và tôi đang gặp rắc rối tìm hiểu hành vi này:Cần giúp đỡ để hiểu ruby ​​của Process.detach

pid = fork do 
    Signal.trap("USR1") do 
    puts "hello!" 
    end 
    Signal.trap("TERM") do 
    puts "Terminating" 
    exit 
    end 
    loop do 
    end 
end 

Process.detach(pid) 

Process.kill("USR1", pid) 
Process.kill("USR1", pid) 
Process.kill("USR1", pid) 
Process.kill("USR1", pid) 

Process.kill("TERM", pid) 

đầu ra này như tôi mong đợi:

hello! 
hello! 
hello! 
hello! 
Terminating 

Tuy nhiên nếu Tôi nhận xét Process.detach, quá trình con dường như chỉ phản hồi tín hiệu một lần (và sau khi chấm dứt?):

Terminating 
hello! 

Tôi đang bối rối là tại sao điều này xảy ra khi tôi không tách rời quá trình, mặc dù tôi đã gửi nó USR1 bốn lần. Ai đó có thể giúp giải thích hành vi này? Tôi nghĩ tôi không hiểu ý nghĩa của việc tách rời một quá trình.

Cảm ơn bạn rất nhiều!

Trả lời

7

Đó là tất cả theo thời gian, tôi nghi ngờ - có nghĩa là, sự khác biệt là do các hướng dẫn của quy trình chính của bạn và quá trình chia hai được lên lịch để chạy tương đối với nhau.

Khi bạn thực hiện Process.detach, một chuỗi mới sẽ được tạo mà chờ kết quả thoát của quá trình đã cho. Bạn có thể thay thế Process.detach bằng

Thread.new { Process.wait(pid) } 

và nhận được tác dụng tương tự. Tôi nghi ngờ rằng gọi tách (và sinh ra một sợi mới) cho quá trình chia đôi của bạn, như là một tác dụng phụ, một cơ hội để được lên kế hoạch.

Nếu bạn không có người tách rời, thì tôi đoán quy trình chia đôi của bạn sẽ không có cơ hội để chạy theo thời gian bạn bảo nó chết.

Bạn có thể thấy ý tôi là thời gian tương đối bằng cách chèn một số lệnh gọi trong mã của bạn để xem bạn có thể nhận được cùng một hành vi được quan sát mà không cần tháo rời hay không.

Ví dụ, điều này dường như làm việc cho tôi, mặc dù mileage của bạn có thể thay đổi tùy thuộc vào nền tảng máy chủ của bạn:

pid = fork do 
    Signal.trap("USR1") do 
    puts "hello!" 
    end 
    Signal.trap("TERM") do 
    puts "Terminating" 
    exit 
    end 
    loop do 
    end 
end 

sleep(1) 

Process.kill("USR1", pid) 
Process.kill("USR1", pid) 
Process.kill("USR1", pid) 
Process.kill("USR1", pid) 

sleep(1) 

Process.kill("TERM", pid) 

này tạo ra:

hello! 
hello! 
hello! 
hello! 
Terminating 
+0

ah, cảm ơn! Vâng tôi đoán lịch trình là những gì là khó hiểu với tôi (Tôi đang ở trên OSX, nên thử nó trên một hộp ảo và xem những gì sẽ xảy ra). – ambertch

Các vấn đề liên quan