Логически, форк создает идентичную копию исходного процесса, которая в значительной степени не зависит от оригинала. По соображениям производительности память используется совместно с семантикой копирования при записи, что означает, что неизмененная память (например, код) остается общей.
Файловые дескрипторы дублируются, так что разветвленный процесс может в принципе захватить соединение с базой данных от имени родителя (или они могут даже совместно взаимодействовать с базой данных, если программист немного искажен). Чаще всего это используется для настройки каналов между процессами, чтобы вы могли написать find -name '*.c' | xargs grep fork
.
Куча других вещей доступна. Подробнее см. здесь .
Одно важное упущение - потоки - дочерний процесс наследует только поток, вызвавший fork()
. Это не создает проблем в многопоточных программах, поскольку состояние мьютексов и т. Д., Которые были заблокированы в родительском объекте, зависит от реализации (и не забывайте, что malloc()
и printf()
используют блокировки внутри). Единственная безопасная вещь, которую нужно сделать в потомке после возвращения fork()
, - это вызвать execve()
как можно скорее, и даже тогда вы должны быть осторожны с файловыми дескрипторами. Смотрите здесь для полной истории ужасов.