Вызов fork()
одновременно запускает новый процесс и продолжает старый.Если есть какая-то ошибка, она возвращает значение ошибки.Все ошибки и только ошибки являются отрицательными числами.Это то, что проверяет первый блок if
.
В новом процессе fork()
возвращает 0. Ветвь, которая увеличивает v
и уменьшает g
, поэтому вызывается только в дочернем процессе, а неparent.
В исходном процессе функция fork()
возвращает идентификатор процесса (PID) дочернего процесса, который является положительным целым числом.(Это будет позже передано waitpid()
. Следовательно, ветвь, которая уменьшает v
и увеличивает g
, вызывается только в родительском процессе, а не в дочернем.
Каждый процесс имеет свою собственную копиюv
и g
. (Это основное различие между процессом и потоком: потоки разделяют память.) В современной операционной системе SMP происходит то, что дочерний процесс получает копию карты памяти родителя.они относятся к одним и тем же страницам физической памяти до тех пор, пока один или другой процесс не выполнит запись в них. Когда это происходит, создается копия этой страницы памяти, и оба процесса теперь получают свои собственные разные копии.
Так как современные ядра Linux реализуют fork()
, дочерний процесс будет продолжаться раньше, чем родительский. Это существенно повлияло на производительность. Большинство программ, которые вызывают fork()
, сразу же вызывают дочерний процесс exec()
для запуска новой программы.означает, что ему вообще не понадобится копия родительской памяти (есть более новая, простаяТеперь можно запустить другую программу в новом процессе, posix_spawn()
.) С другой стороны, родительский процесс почти всегда продолжает работать и изменять свою память.Следовательно, предоставление ребенку возможности заявить, что он собирается отбросить память, которую он унаследовал, означает, что родителю не нужно беспокоиться о том, чтобы оставить неизмененную копию каких-либо страниц памяти для своих детей, и ядру не нужно проходить черезРигмарол копирования при записи.
На практике, однако, любой приличный компилятор будет хранить обе локальные переменные в регистрах, поэтому эта проблема не возникнет.
На следующей итерациицикл, который происходит только после завершения дочернего процесса, порождает новый дочерний процесс, используя обновленные значения родительских переменных.Каждый дочерний процесс также продолжает запускать цикл с теми же значениями v
и g
, которые он унаследовал от своего родителя.