Linux / Perl - Что происходит, когда процесс разветвляется?

2054
somebody

Я читал о форке и, насколько я понимаю, процесс клонирован, но какой процесс? Сам скрипт или процесс, который запустил скрипт?

Например:

Я запускаю rTorrent на своей машине, и когда торрент завершается, у меня запускается скрипт. Этот скрипт извлекает данные из Интернета, поэтому для его завершения требуется несколько секунд. В это время мой рторрент-процесс завис. Поэтому я сделал скрипт форка, используя следующую

my $pid = fork(); if ($pid) == 0) { blah blah blah; exit 0; } 

Если я запускаю этот скрипт из CLI, он возвращается к оболочке в течение секунды, пока он работает в фоновом режиме, именно так, как я и предполагал. Однако когда я запускаю его из rTorrent, он кажется еще медленнее, чем раньше. Так что именно было разветвлено? Клонировал ли сам процесс rtorrent, и мой сценарий выполнялся таким образом, или мой сценарий клонировался сам? Я надеюсь это имеет смысл.

5
Вам, вероятно, лучше спросить о Stackoverflow. Unfundednut 14 лет назад 0
У rTorrent могут быть каналы настройки для дочернего элемента std . Если это так, вам может потребоваться закрыть их (или закрыть и повторно открыть выходные дескрипторы для некоторого файла журнала, если это важно), прежде чем будет продолжен rTorrent. Chris Johnsen 14 лет назад 1

1 ответ на вопрос

3
Greg Bacon

Из Расширенного программирования в среде UNIX У. Ричарда Стивенса (стр. 188):

8,3 forkфункция

Только путь новый процесс создается ядром Unix, когда существующий процесс вызывает forkфункцию. (Это не относится к специальным процессам, которые мы упомянули в предыдущем разделе - initswapper и pagedaemon. Эти процессы специально создаются ядром как часть начальной загрузки.)

#include <sys/types.h> #include <unistd.h>  pid_t fork(void); /* Returns: 0 in child, process ID of child in parent, -1 on error */ 

Новый созданный процесс forkназывается дочерним процессом . Функция вызывается один раз, но возвращается дважды. Единственная разница в возвращаемых значениях заключается в том, что возвращаемое значение в дочернем элементе равно 0, а возвращаемое значение в родительском элементе является идентификатором процесса нового дочернего элемента. Причина, по которой идентификатор дочернего процесса возвращается родителю, состоит в том, что у процесса может быть более одного дочернего элемента, поэтому нет функции, которая позволяла бы процессу получать идентификаторы процессов своих дочерних элементов. Причина forkвозвращает 0 дочернему элементу в том, что у процесса может быть только один родительский элемент, поэтому дочерний элемент всегда может вызывать getppidдля получения идентификатора процесса своего родительского элемента. (Идентификатор процесса 0 всегда используется подкачкой, поэтому 0 не может быть идентификатором процесса дочернего элемента.)

И ребенок, и родитель продолжают выполнение с инструкцией, следующей за вызовом fork. Ребенок является копией родителя. Например, потомок получает копию пространства данных, кучи и стека родителя. Обратите внимание, что это копия для дочернего элемента - родитель и дочерний элемент не разделяют эти части памяти. Часто родитель и потомок разделяют текстовый сегмент (раздел 7.6), если он доступен только для чтения.

В Linux forkоператор Perl вызывает систему forkи возвращает undefпри ошибке, а не -1.

Стивенс приводит списки (стр. 192) наследуемых свойств и различий между родительскими процессами и их раздвоенными детьми:

Помимо открытых файлов, существует множество других свойств родителя, которые наследуются дочерним элементом:

  • реальный идентификатор пользователя, реальный идентификатор группы, эффективный идентификатор пользователя, эффективный идентификатор группы
  • идентификаторы дополнительных групп
  • ID группы процессов
  • идентификатор сессии
  • управляющий терминал
  • флаг set-user-ID и флаг set-group-ID
  • текущий рабочий каталог
  • корневая директория
  • маска создания режима файла
  • сигнальная маска и диспозиции
  • флаг close-on-exec для любых открытых файловых дескрипторов
  • среда
  • прикрепленные сегменты общей памяти
  • пределы ресурса

Различия между родителем и ребенком

  • возвращаемое значение от fork
  • идентификаторы процессов разные
  • два процесса имеют разные идентификаторы родительских процессов - родительский идентификатор родительского процесса; идентификатор родительского процесса не меняется
  • ценности ребенка для tms_utime, tms_stime, tms_cutimeи tms_ustimeустанавливаются в 0
  • блокировки файлов, установленные родителем, не наследуются дочерним
  • ожидающие тревоги очищаются для ребенка
  • набор ожидающих сигналов для ребенка устанавливается в пустой набор

Похожие вопросы