Я запускаю этот скрипт:
t = fork do
Signal.trap "INT" do
puts "child"
exit
end
sleep 10
end
Signal.trap "INT" do
puts "parent"
Process.kill "INT", t
Process.waitpid t
exit
end
Process.waitpid t
Когда я нажимаю CTRL + C, я получаю
$ ruby sigtest.rb
^Cchild
parent
Вы можете видеть, что "INT" передается каждому процессу и Process.kill "INT", t
пытается убить процесс, который уже умер. Есть ли способ сделать так, чтобы пользовательский сигнал INT передавался только родителю? И вывод будет:
$ ruby sigtest.rb
^Cparent
child
Решение
Правила:
- Когда вы нажимаете Ctrl + C, SIGINT передается всей группе процессов.
- Когда вы создаете новый процесс, обработчики сигналов не передаются новому процессу
Так что, если вы хотите управлять дочерними сигналами процесса вручную, вам нужно изменить GID процесса.
См.
def system cmd
pid = fork do
exec cmd, {:pgroup => true}
end
Process.wait pid
$?.success?
end
def ` cmd # `make syntax highlight happy
readme, writeme = IO.pipe
pid = fork do
$stdout.reopen writeme
readme.close
exec cmd, {:pgroup => true}
end
writeme.close
data = readme.read
Process.wait pid
data
end