Дочерние процессы - вопрос по теоретическому материалу

Для новичков как вообще в Linux, так и в конкретной теме, к которой относится вопрос.

Модератор: Bizdelnick

Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

Читаю лекцию, но не до конца все понял, не растолкуете?
Для работы командного интерпретатора одного exec() недостаточно. В самом деле, shell не просто запускает утилиту, а дожидается ее завершения, обрабатывает результаты ее работы и продолжает диалог с пользователем. Для этого в Linux служит системный вызов fork() ("вилка, развилка"), применение которого приводит к возникновению еще одного, дочернего, процесса – точной копии породившего его родительского. Дочерний процесс ничем не отличается от родительского: имеет такое же окружение, те же стандартный ввод и стандартный вывод, одинаковое содержимое памяти и продолжает работу с той же самой точки (возврат из fork()). Отличий два: во-первых, эти процессы имеют разные PID, под которыми они зарегистрированы в таблице процессов, а во-вторых, различается возвращаемое значение fork(): родительский процесс получает в качестве результата fork() идентификатор процесса-потомка, а процесс-потомок получает "0".

Дальнейшие действия shell при запуске какой-либо программы очевидны. Shell-потомок немедленно вызывает эту программу с помощью exec(), а shell-родитель дожидается завершения работы процесса-потомка (PID которого ему известен) с помощью еще одного системного вызова, wait(). Дождавшись и проанализировав результат команды, shell продолжает работу


Порождается копия родительского процесса - дочерний ... с помощью него выполняется программа. А дальше как ? результат деятельности дочернего
идет в родительский, а дочерний убивается ? так, что ли? И еще не ясна строка выделенная жирным.
Ну не смешно ли?
Спасибо сказали:
Аватара пользователя
anonymous.ru
Сообщения: 614

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение anonymous.ru »

Xlight писал(а): ↑
26.07.2007 13:20
Читаю лекцию, но не до конца все понял, не растолкуете?
Для работы командного интерпретатора одного exec() недостаточно. В самом деле, shell не просто запускает утилиту, а дожидается ее завершения, обрабатывает результаты ее работы и продолжает диалог с пользователем. Для этого в Linux служит системный вызов fork() ("вилка, развилка"), применение которого приводит к возникновению еще одного, дочернего, процесса – точной копии породившего его родительского. Дочерний процесс ничем не отличается от родительского: имеет такое же окружение, те же стандартный ввод и стандартный вывод, одинаковое содержимое памяти и продолжает работу с той же самой точки (возврат из fork()). Отличий два: во-первых, эти процессы имеют разные PID, под которыми они зарегистрированы в таблице процессов, а во-вторых, различается возвращаемое значение fork(): родительский процесс получает в качестве результата fork() идентификатор процесса-потомка, а процесс-потомок получает "0".


Порождается копия родительского процесса - дочерний ... с помощью него выполняется программа. А дальше как ? результат деятельности дочернего
идет в родительский, а дочерний убивается ? так, что ли? И еще не ясна строка выделенная жирным.


Доброе утро, коллега :)

важно:
после форка мы имеем два независимых процесса, которые выполняют один и тот же программный код.
с точки зрения планировщика ядра - процессы равны и планируются на процессор независимо, как равные.
Тоесть неясно кто первым получит процессорное время после форка.

У нас появился новый процесс. Какой у него программный код? - тот же что и у родителя.
С какой строчки куда, с какой инструкции начнет выполняться новый процесс? - с той же что и отец, со следующий инструкции после форка.
Форк забавен тем, что в отличии от других системных вызовов, форк вызывается одним процессом, а возврат надо делать в два ))

Дальше )) у нас есть два процесса, с одинаковым кодом, которые выполняются с одного и того же места ))
как в программе х отличить друг от друга?? Анализировать pid до и после форка?? если он измениться то мы в сыне??
можно так, но можно проще.
у каждого системного вызова есть код возврата, -1 в качестве ошибки или обычно результат операции, так вот как раз в отца возвращается pid сына (как результат), ведь именно отец просил создать новый процесс. а в сына возвращается 0 - тоесть система говори, что ТЫ сын, ТЫ сан результат форка ))


дальше в коде следуют условие
if (pid=fork())
{ отец
}
else
{ сын
}


А как в сына загрузить новый код??
А действительно ли при форке копируются все сегменты данных отца??
а если мы хотим из большой программки (размером пару гигов в памяти)
запустить маленькую (типа ls)
неужели надо копировать все эти два гига ненужного кода??

:)
:drinks:
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение serzh-z »

Никто не убивается - работают оба процесса. Родитель может ожидать завершения потомка с помощью wait().

Xlight писал(а): ↑
26.07.2007 13:20
И еще не ясна строка выделенная жирным.

Код: Выделить всё

if (fork())
       printf("I'm parent\n");
    else printf("I'm child\n");
После вызова fork() начинается "развоение личности", каждая из "личностей" продолжает выполняться дальше с того же места, как ни в чём не бывало, осознать себя ("кто же я?") каждый из двух процессов может лишь проанализировав возвр. знач. от fork(). Вообще, рекомендую посмотреть фильм "Престиж". :)
Спасибо сказали:
Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

Спасибо всем ... кое что начинает проясняться, но каши пока еще много в голове ...
очень понравился ответ анонимуса ... не до конца его местами понял ... т.к. нехватило некоторых предварительных знаний, но общую картину вроде сложил )

Вообще, рекомендую посмотреть фильм "Престиж"

Смотрел ) там команда kill по отношению к дочерним процессам, натурально радовала того парня :)
Ну не смешно ли?
Спасибо сказали:
Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

Попробую покоментить ...
важно:
после форка мы имеем два независимых процесса, которые выполняют один и тот же программный код.
с точки зрения планировщика ядра - процессы равны и планируются на процессор независимо, как равные.
Тоесть неясно кто первым получит процессорное время после форка.

Форк - системный вызов, дающий команду отклонировать процесс, после подачи этого сигнала - у нас два идентичных процесса родит. и дочерн. так получается ? :)
У нас появился новый процесс. Какой у него программный код? - тот же что и у родителя.
С какой строчки куда, с какой инструкции начнет выполняться новый процесс? - с той же что и отец, со следующий инструкции после форка.


процесс - программа в стадии выполнения ... это стадия выполнения её кода ... то есть дочерний процесс выполняет тот же код по тому же пути ... с той же строчки на какой находился родительский, в момент форка ... "с той же инструкции" вот тут непонял, что имелось в виду ...

Форк забавен тем, что в отличии от других системных вызовов, форк вызывается одним процессом, а возврат надо делать в два ))

Эту строчку интуитивно понимаю - но обьяснить бы не смог ... если можно - прокоментируйте её ...

у каждого системного вызова есть код возврата
поподробней, если можно ... далее логическая нить ускользает ...

P.S хреново быть Блондинко :)
Ну не смешно ли?
Спасибо сказали:
Аватара пользователя
anonymous.ru
Сообщения: 614

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение anonymous.ru »

Xlight писал(а): ↑
26.07.2007 14:03
процесс - программа в стадии выполнения ... это стадия выполнения её кода ... то есть дочерний процесс выполняет тот же код по тому же пути ... с той же строчки на какой находился родительский, в момент форка ... "с той же инструкции" вот тут непонял, что имелось в виду ...


Тоже самое )) что и "строчка кода" ) считай что синонимы )) с той же инструкции CPU ))

Xlight писал(а): ↑
26.07.2007 14:03
у нас два идентичных процесса родит. и дочерн. так получается ?


Да )) почти, pid и ppid у них будут разные - это самое очевидное отличии.
есть еще несколько менее очевидных.
так, например для сына будут сброшен список сигналов, ожидающих обработки (очевидно мы посылали сигналы конкретному процессу - отцу, и сын не должен на них реагировать) флаги процесса, так же будут другими ))


Xlight писал(а): ↑
26.07.2007 14:03
Цитата
у каждого системного вызова есть код возврата
поподробней, если можно ... далее логическая нить ускользает ...


тут я не корректно выразился.
есть возвращаемое значение )
системный вызов для программиста выглядит как функция )
pid=fork();
результат работы функции запишется в переменную


... пойду обедать, а то все вкусное съедят!
потом продолжу
:drinks:
Спасибо сказали:
Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

тут я не корректно выразился.
есть возвращаемое значение )
системный вызов для программиста выглядит как функция )
pid=fork();
результат работы функции запишется в переменную

Так - ясно :)
Буду ожидать продолжения :)
Ну не смешно ли?
Спасибо сказали:
Аватара пользователя
anonymous.ru
Сообщения: 614

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение anonymous.ru »

Xlight писал(а): ↑
26.07.2007 14:03
Эту строчку интуитивно понимаю - но обьяснить бы не смог ... если можно - прокоментируйте её ...


Xlight, конечно можно и прокомментировать ))
Но лучше что бы ты формулировал бы законченные вопросы, а я бы на них отвечал )) так ты быстрее разберешься (помнишь грамотно сформулированный вопрос, содержит половину ответа )) )

Что такое вообще системный вызов??
С точки зрения программеров - просто функция на Cи.
С точки зрения процесса - это обращение к сервисам (к услугам) ядра ОС.
Типа- ядро, а открой ка мне файл, а роди ка мне сына, а испеки ка мне колобка ))
именно ядро выполняет весь код, связанный с системным вызовом.
тоесть нормальная работа процесса - прерывается, происходит переключение в контекст ядра. Ядро выполняет действия и в конце должно вернуть процессу управление (сделать возврат в процесс) и передать процессу результат своей работы ))
Так вот, для большинства системных вызовов ситуация проста и очевидно:
1)переключается из контекста процесса (из юзер спейс ) в режим ядра
2) выполняем системный вызов
3) переключаемая (возвращаемся) обратно в процесс, который дергал системный вызов (а так же передаем результат или информацию о результате работы системного вызова)

Если мы говори о системном вызове fork(), то до его работы у нас был один процесс, а после стало два. И оба эти процесса должны продолжить свою работу. Тоесть вернуться(передать управление, выделить квант процессорного времени) надо и в отца и сына.
Конечно, если процессор у нас один, мы сначало вернемся в один процесс, потом дадим ему поработать, потом планировщик ядра переключит на процессор другой процес.
Еще раз повторюсь: никто не гарантирует какой либо очередности выполнения отца и сына после окончания fork()
Может после форка первым начнет работать (получит процессорное время) отец, а затем сын. А может на оборот.


PS Ты какую книжку читаешь?
Советую для начало Робачевского.
:drinks:
Спасибо сказали:
Аватара пользователя
anonymous.ru
Сообщения: 614

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение anonymous.ru »

Xlight писал(а): ↑
26.07.2007 13:20
Дальнейшие действия shell при запуске какой-либо программы очевидны. Shell-потомок немедленно вызывает эту программу с помощью exec(), а shell-родитель дожидается завершения работы процесса-потомка (PID которого ему известен) с помощью еще одного системного вызова, wait(). Дождавшись и проанализировав результат команды, shell продолжает работу


Порождается копия родительского процесса - дочерний ... с помощью него выполняется программа. А дальше как ? результат деятельности дочернего
идет в родительский, а дочерний убивается ? так, что ли? И еще не ясна строка выделенная жирным.


И так, теперь у нас есть два независимых процесса, которые могут выполняться параллельно.
В сына мы загружаем новы программный код из бинарного файла (по средствам вызова из семейства exec*)
А что делать отцу?
он может продолжать работать, а может ничего не делать дожидаясь смерти(завершения работы ) сына.
Если отец хоче подождать, когда сын завершиться - он вызывает wait()
В это случае ядро больше не будет планировать этот процесс на процессор, до тех пор пока один из сыновей этого процесса не завершиться.
:drinks:
Спасибо сказали:
Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

Xlight, конечно можно и прокомментировать ))
Но лучше что бы ты формулировал бы законченные вопросы, а я бы на них отвечал )) так ты быстрее разберешься (помнишь грамотно сформулированный вопрос, содержит половину ответа )) )

Непреложная истина!
Все остальное

Спасибо огромное - многое прояснилось для меня - очень многое из того, что я знал, но не понимал - сложилось в общую картину ...
Теперь я попробую по порядку разложить последовательность действий при запуске дочернего процесса, если буду где неправ - поправьте пожалуйста.

1. у нас есть запущенный процесс bash который все время в садии выполнения (ждет от нас команд)
2. мы даем команду и посылается системный вызов fork()
3. вследствии его работы становится два процесса ... отец, который на время становится фоновым процессом и выполняет там wait()
и сын, который становится активным процессом и выполняет команду с помощью exec() то есть заменяя себя, как бы свой процесс bash на тот, который был задан командой ...
4. После выполнения команды сын отправляет результат отцу и передает ему обратно управление и тот выходит из фонового ... а дочерний процесс завершается ...
Ну не смешно ли?
Спасибо сказали:
Аватара пользователя
anonymous.ru
Сообщения: 614

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение anonymous.ru »

serzh-z писал(а): ↑
26.07.2007 13:38
Вообще, рекомендую посмотреть фильм "Престиж". :)



что за фильм???
Это? http://ru.wikipedia.org/wiki/%D0%9F%D1%80%...BB%D1%8C%D0%BC)
:drinks:
Спасибо сказали:
Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

P.S. Робачевский дома лежит - почитываю и его ... но в данный момент смотрю в сторону intuit-а (онлайн университет)
http://www.intuit.ru/department/os/linux/class/free/5/ - по моему классные лекции ... я раньше вообще столько времени гробил, силясь понять хоть что
то, а сейчас легче пошло ... начинаю проникаться :))

что за фильм???

Да он ... разок можно глянуть :)
Ну не смешно ли?
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение serzh-z »

Xlight писал(а): ↑
26.07.2007 16:10
разок можно глянуть :)
Он очень точно показывает как работает вызов fork(), и в какие чувства испытывают порождённые процессы... ;-)
Спасибо сказали:
Аватара пользователя
malex
Сообщения: 374
ОС: debian

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение malex »

а как же демоны? там же родитель по идее завершается а потомок работает далее. или нет?
Ну вот, еще один день прошел, а мы все еще живы. И может быть стали умнее.
Спасибо сказали:
Аватара пользователя
anonymous.ru
Сообщения: 614

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение anonymous.ru »

Xlight писал(а): ↑
26.07.2007 16:07
4. После выполнения команды сын отправляет результат отцу и передает ему обратно управление и тот выходит из фонового ... а дочерний процесс завершается ...


Не совсем так.
Родитель вызвал wait(), переключился в режим ядра. Ядро поменяла статус процессу, отложила его в сторону, до лучших времен.
Сын работает и через некоторое время завершиться (я надеюсь :) ). Завершиться самостоятельно, вызвав exit(), или принудительно получив сигнал со стороны.
Процесс завершается, становясь Зомби )
Поскольку завершения процесса обрабатывается ядром, оно (ядро) заодно проверяет- не ждет ли кто-нить смерти этого процесса.
В нашем случае ядро наконец то отпускает отца из системного вызова wait. И отец продолжает свою работу.

Что касается кода возврата процесса (оно же статус процесса, или статус завершение процесса)
это то что мы можем указать как параметр exit
тоесть exit(0) или exit(1) (или тоже самое в return из main)
Если упростить, то вот это число и будет передано отцу ядром в момент возврата из wait ))

А если сына убили сигналом, мы получим номер этого сигнала в коде возврата.

))

А как не перепутать exit(9) и kill 9 ???

malex писал(а): ↑
26.07.2007 16:19
а как же демоны? там же родитель по идее завершается а потомок работает далее. или нет?



да именно так )) есть такие осиротевшие процессы, но их усыновляет добрый дядя init

об этом пойже
:drinks:
Спасибо сказали:
Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

Что касается кода возврата процесса (оно же статус процесса, или статус завершение процесса)
это то что мы можем указать как параметр exit
тоесть exit(0) или exit(1) (или тоже самое в return из main)
Если упростить, то вот это число и будет передано отцу ядром в момент возврата из wait ))


Вот это сложновато для меня ...
exit() - это функция (системный вызов на завершение процесса)
её либо вызавает сама программа, либо пользователь, которому надоело ждать <ctrl> + D или <ctrl> + C или вообще:
$ kill 9 "program name"
А к чему тут было сказанно, "это то что мы можем указать как параметр exit" я непонял ... как мы можем указать ?

P.S. Я так докапываю - ибо anonymous.ru хороший учитель ... почти все, что сказанно было очень полезно мне ... вот и пытаюсь как можно более инф. получить ... а так да ... нубка я .. :)
Ну не смешно ли?
Спасибо сказали:
Аватара пользователя
anonymous.ru
Сообщения: 614

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение anonymous.ru »

Xlight писал(а): ↑
26.07.2007 16:44
А к чему тут было сказанно, "это то что мы можем указать как параметр exit" я непонял ... как мы можем указать ?


Мы в смысле программисты ) - авторы программы

Или скажем так: процесс может добровольно умереть, а точнее попросить ядро ОС о смерти.
"Ядро, убей меня и сообщи моему отцу что я выполнил его просьбу (или наоборот не выполнил :( ) "

для примера:
в шеле можно узнать код возврата последней завершившейся команды
попробуй

true
echo $?
false
echo $?

Вариант номер два, процесс не просит о смерти хочет жить и работать, но его убивают - сигналом в спину.
Тогда ядро сообщает родителю, что его сын погиб в неравном бою от рук сигнала номер такой та.

кстати нажатие комбинаций клавиш тоже приводит к посылки сигнала

пример, пробуй

sleep 10000
^C
echo $?
:drinks:
Спасибо сказали:
Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

130 - ым его завалило ... вроде более-мение разобрался :)

"Ядро, убей меня и сообщи моему отцу что я выполнил его просьбу (или наоборот не выполнил :( ) "

LOL !! До сих пор смешно ... наглядно излагаете )))
Ну не смешно ли?
Спасибо сказали:
Аватара пользователя
anonymous.ru
Сообщения: 614

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение anonymous.ru »

Xlight писал(а): ↑
26.07.2007 17:12
130 - ым его завалило ... вроде более-мение разобрался :)


Ну почти.
Вопрос в следующем:
У нас есть сигнал номер 9
И в системном вызове нам (программистам) никто не мешает написать exit(9)

Так вот, код возврата чуть сложнее чем кажется.
Он состоит из двух байт.
В одном из них может храниться номер сигнала, которым нас убили, а в другом то число, которое мы написали в exit()
:drinks:
Спасибо сказали:
Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

"В одном из них может храниться номер сигнала, которым нас убили, а в другом то число, которое мы написали в exit()"

И зачем это сделано ? 1-го байта недостаточно только для номера сигнала, которым убили ?
Ну не смешно ли?
Спасибо сказали:
Аватара пользователя
anonymous.ru
Сообщения: 614

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение anonymous.ru »

Xlight писал(а): ↑
26.07.2007 17:34
И зачем это сделано ? 1-го байта недостаточно только для номера сигнала, которым убили ?


сигналов в linux всего 64 (в других юниксах может быть даже меньше)

Интересно, что сигнала с номером 130 не существует.
комбинация клавиш Ctrl+C приводит к посылки сигнала номер 2 (SIGINT) группе процессов, которая сейчас связанна с терминалом.

Но вот незадача, подумай и ответь, сможет ли отец понять убили ли сына сигналом номер 2 или сын сам умер, передав exit в качестве параметра число 2. :unsure: Это две абсолютно разные ситуации, в первой сын погиб и наверно не успел сделать все то, на что мог расчитывать отец, во втором сын сообщает о успешном завершении своей жизни и (возможно) задачи.
:drinks:
Спасибо сказали:
Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

1-ый байт - хранит информацию о номере сигнала, которым убили в спину, второй, о номере сигнала, которым бы убили бы "естественным образом" запрограммировав заранее ... на основе этой информации отец может сделать вывод о том, какой смертью пал сын ... но тогда я не понимаю откуда взялось 130-ть и что это такое, раз сигнала с таким номером нет ...
P.S. я реально достал ... уже даже сам себя ... просто завтра на свежую голову перечитаю всю тему и наверняка, все прояснится ...
Ну не смешно ли?
Спасибо сказали:
Аватара пользователя
malex
Сообщения: 374
ОС: debian

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение malex »

anonymous.ru - спасибо! очень вразумительно и доходчиво!

зы. модераторы - может перенести этот топик в "программирование для начинающих" и закрепить там?
Ну вот, еще один день прошел, а мы все еще живы. И может быть стали умнее.
Спасибо сказали:
Аватара пользователя
Xlight
Сообщения: 139
ОС: FreeBSD-8.1

Re: Дочерние процессы - вопрос по теоретическому материалу

Сообщение Xlight »

Код возврата, это число передаваемое от закончившего работу процесса - ядру, которое в свою очередь проверяет не ждет ли кто окончания работы данного процесса, и в случае если ждет - передает этот код ему ... далее ядро передает управление ожидавшему процессу, а тот в свою очередь выбирает дальнейшие действия, исходя из кода возврата т.е если один код возврата - процесс понимает ... оппа ... он все выполнил, и самозавершился естественным образом, и как то получает результат деятельности ... если другой, то оппа его убили ... и он понимает, что надо сообщить, что результата нет ...
Вот единственное, что не до конца понятно, это по какому принципу "формируется" код возврата ...
Ну не смешно ли?
Спасибо сказали: