Pull to refresh

fork() может потерпеть неудачу: это важно

Reading time 1 min
Views 26K
Original author: Rachel Kroll
Эх, fork(). Одни процессы порождают другие. Кажется, у меня есть история об этом.

Форк может потерпеть неудачу. Понимаете? В самом деле, понимаете? Это очень серьёзно. Форк может завершиться с ошибкой. Так же, как и malloc. Нечасто, но когда такое происходит, нельзя просто взять и игнорировать это. Вы должны что-то предпринять в таком случае.

Похоже, всем известно, что fork возвращает дочернему процессу 0, а родителю некоторое положительное число — pid ребенка. Он выдаёт этот номер, который используется позже.

Угадайте, что происходит, когда вы не проверяете ответ на ошибку? Да, вы обработаете "-1" (ошибка форка) в качестве валидного pid.

Это только начало. Настоящая боль начинается позже, когда приходит время послать сигнал. Может, вы захотите закрыть дочерний процесс.

Вы делаете kill(pid, signal). Например, kill(pid, 9).

Что происходит, когда когда pid равен -1? Это действительно важно знать. Реально важно.





Здесь я вставлю со справочной страницы kill(2) со своего Linux.

Если pid равен -1, то sig отправляется каждому процессу, для которого вызывающий процесс имеет разрешение на отправку сигналов, за исключением процесса 1(init)...

Видите? Убить pid -1 эквивалентно уничтожению всех остальных процессов. Если вы рут, то на этом всё закончилось. Остались вы и init. Всё остальное ушло, ушло, ушло.

У вас есть код, который управляет процессами? Когда-нибудь находили машину полностью мертвой, за исключением текстовой консоли getty/login (которых перезапускает init, естественно) и менеджера процессов? Наверное, винили в этом oomkiller в ядре?

Возможно, он не виноват. Лучше проверьте, что вы не запустили kill(-1).

В Unix достаточно ловушек и медвежьих капканов на любой вкус.
Tags:
Hubs:
+149
Comments 256
Comments Comments 256

Articles