На самом деле, в отличие от многих основных функций UNIX, fork
был относительно поздним (a) .
Самое раннее существование нескольких процессов в UNIX состояло из нескольких (исправленочисло процессов), один на терминал, который был подключен к машине PDP-7 (b) .
Основная идея заключалась в том, что процесс оболочки для данного терминала будет принимать команду отПользователь, найдите файл программы, загрузите небольшую программу начальной загрузки в верхнюю память и перейдите к ней, передав достаточно информации для кода начальной загрузки, чтобы загрузить файл программы.
Код начальной загрузки после загрузки программы в нижнюю частьпамять (перезаписывая оболочку), затем перейдет к ней.
Когда программа будет завершена, она вызовет exit
, но это не было похоже на exit
, который мы знаем и любим сегодня. Этот exit
просто перезагрузит оболочку и запустит ее, используя в основном тот же метод, который использовался для загрузки программы.
Так что это действительно больше похоже на элементарный exec
команда, которая заменяет вашу текущую программу другой, в том же пространстве процесса.
Оболочка будет exec
вашей программой, затем, когда ваша программа будет завершена, она снова будет exec
оболочкойВызов exit
.
Этот метод был аналогичен тому, который использовался во многих других интерактивных системах того времени, включая Multics, откуда UNIX получил свое имя.
Из двусторонней exec
, это был не такой большой скачок к добавлению fork
в качестве дубликатора процессов для совместной работы.В то время как многие системы запускают другую программу напрямую, именно этот метод «просто добавь то, что нужно» отвечает за разделение обязанностей между fork
и exec
в UNIX.Это также привело к очень простой fork
функции.
Если вас интересует ранняя история различных функций (c) Unix, вы не можете Пройдите мимо статьи Денниса Ритчи The Evolution of the Unix Time-Sharing System
, представленной на конференции 1979 года в Австралии и впоследствии опубликованной AT & T.
(a) Хотя я имею в виду опоздавшего в том смысле,что разделение четырех фундаментальных сил во вселенной было «поздним», происходившим примерно через 0,00000000001 секунд после большого взрыва. .
(b) Поскольку вопросбыл поднят в комментарии о том, как изначально были запущены оболочки, есть большой ресурс с очень ранним исходным кодом для Unix на Unix Heritage Society , в частности архивы исходного кода и, в частности, первое издание .
Файл init.s
из первого издания показывает, как было создано фиксированное число процессов оболочки (слегка переформатировано):
...
mov $itab, r1 / address of table to r1
1:
mov (r1)+, r0 / 'x, x=0, 1... to r0
beq 1f / branch if table end
movb r0, ttyx+8 / put symbol in ttyx
jsr pc, dfork / go to make new init for this ttyx
mov r0, (r1)+ / save child id in word offer '0, '1, etc
br 1b / set up next child
1:
...
itab:
'0; ..
'1; ..
'2; ..
'3; ..
'4; ..
'5; ..
'6; ..
'7; ..
0
Здесь вы можете увидеть фрагмент, который создает процессы для каждого подключенного терминала.Это дни жестко закодированных значений, при этом не требуется автоматическое определение количества терминалов.Таблица с нулевым символом в конце itab
используется для создания ряда процессов, и, надеюсь, комментарии кода объясняют, как (единственный сложный бит это метки - хотя есть несколько меток 1
, вы переходите к ближайшемуодин в заданном направлении, поэтому 1b
означает ближайшую метку 1
в обратном направлении).
Показанный код просто обрабатывает таблицу, вызывая dfork
, чтобы создать процесс для каждого терминала и запуститьgetty
, приглашение для входа.Программа getty
, в свою очередь, в конечном итоге запустила оболочку.С этого момента, как я описал в основной части этого ответа.
(c) Нет путей (и использование временных ссылок, чтобы обойти это ограничение), ограниченопроцессы, почему в файле паролей есть поле GECOS, и всякие другие мелочи, которые, как правило, интересны только любителям компьютерных игр, конечно.