Проблема в том, что вызов system
создает еще один дочерний процесс, выполняющий данную команду в подоболочке, поэтому в вашем примере фактически выполняются три процесса. Кроме того, команда Ruby Kernel#system
реализована через стандартную функцию C system (3) , которая вызывает fork
и exec
для создания нового процесса и (в большинстве систем) игнорирует SIGINT и SIGQUIT и блокирует SIGCHLD.
Если вы просто позвоните sleep(10000)
вместо system("sleep 10000")
, тогда все должно работать так, как вы ожидаете. Вы также можете поймать SIGQUIT в ребенка, чтобы изящно с ним справиться:
child = fork do
Signal.trap("QUIT") { puts "CHILD: ok, quitting time!"; exit }
sleep(10000)
end
Если вам действительно нужно использовать «системный» вызов от дочернего процесса, то вам может быть лучше использовать явную пару fork / exec (вместо неявных в вызове system
), чтобы вы могли выполнить Ваша собственная обработка сигналов у третьего разветвленного ребенка.