Подтвердить что ты не робот

Прерывание ребенка, вызванное из рубина

Почему прерывание рубинового процесса с потомком, созданным с помощью вызова system, не прерывает сам процесс ruby? Они должны принадлежать к одной группе, поэтому их следует прервать. Также это недействительно для ruby2.0.

Учитывая ruby ​​1.8.7 patch 371, ruby ​​1.9.3 patch 392 и ruby2.0 patch 0:

Запуск ruby1.8 -e 'system "sleep 100"; p $?; sleep' в bash и нажатие ^ C убивает только внутренний вызов sleep 100.

Ruby 1.9 ведет себя одинаково.

Хотя запуск ruby2.0 -e 'system "sleep 100"; p $?; sleep' прерывает как внутренний, так и рубиновый процесс. 2.0.0-p0

- EDIT -

Источники чтения. Я обнаружил, что обработка SIGINT, SIGQUIT и SIGHUP переключается на игнорирование в методе rb_syswait, чем ожидает завершения созданного подпроцесса, а затем восстанавливает обработчики (rb_syswaitin ruby ​​v1.8.7-p370, ruby ​​v1.9.3-p362 и без блокировки обработчиков в ruby ​​v2.0.0-p0).

Почему это сделано и почему только для system и IO.popen, а не %x{} или fork{}?

4b9b3361

Ответ 1

Для обходного пути вы можете распространять SIGINT самостоятельно. Вы можете проверить, вышла ли системная команда из-за сигнала, и если это так, поднимите SIGINT:

ruby1.8 -e 'system "sleep 100"; p $?; Process.kill("INT",0) if $?.signaled?; sleep'

Ответ 2

Это, похоже, не вопрос Ruby, а ваша операционная система, которую вы не указали. Группировка процессов и низкоуровневая системная маршрутизация выполняются ядром ОС.