В чем разница между вилкой и резьбой?

Ответы:

98

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

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

Дакав
источник
3
Вероятно, вы захотите назвать «копию текущего процесса» дочерним процессом.
1
Однако текстовый сегмент часто используется совместно (виртуально), и даже сегмент данных может быть скопирован при записи.
Jé Queue
Ответ: НЕТ stackoverflow.com/questions/10080811/…
Майкл
78

Вилка

Fork - это не что иное, как новый процесс, который выглядит точно так же, как старый или родительский процесс, но все же это другой процесс с другим идентификатором процесса и собственной памятью. Родительский процесс создает отдельное адресное пространство для дочернего. И родительский, и дочерний процесс имеют один и тот же сегмент кода, но выполняются независимо друг от друга.

Самый простой пример разветвления - это когда вы запускаете команду в оболочке в Unix / Linux. Каждый раз, когда пользователь выдает команду, оболочка создает дочерний процесс, и задача выполняется.

Когда выполняется системный вызов fork, создается копия всех страниц, соответствующих родительскому процессу, которые загружаются в отдельную ячейку памяти ОС для дочернего процесса, но в некоторых случаях это не требуется. Как и в случае системных вызовов exec, нет необходимости копировать страницы родительского процесса, поскольку execv заменяет адресное пространство самого родительского процесса.

Несколько замечаний по поводу разветвления:

  • Дочерний процесс будет иметь собственный уникальный идентификатор процесса.
  • Дочерний процесс должен иметь собственную копию дескриптора родительского файла.
  • Блокировки файлов, установленные родительским процессом, не должны наследоваться дочерним процессом.
  • Любые семафоры, открытые в родительском процессе, также должны быть открыты в дочернем процессе.
  • Дочерний процесс должен иметь свою собственную копию дескрипторов родительской очереди сообщений.
  • У ребенка будет свое адресное пространство и память.

Потоки

Потоки - это облегченные процессы (LWP). Традиционно поток - это просто состояние ЦП (и некоторого другого минимального состояния), а процесс содержит все остальное (данные, стек, ввод-вывод, сигналы). Потоки требуют меньше накладных расходов, чем «разветвление» или порождение нового процесса, потому что система не инициализирует новое системное пространство виртуальной памяти и среду для процесса. Хотя наиболее эффективен в многопроцессорной системе, где поток процесса может быть запланирован для выполнения на другом процессоре, таким образом увеличивая скорость за счет параллельной или распределенной обработки, выигрыш также можно найти в однопроцессорных системах, которые используют задержку ввода-вывода и другие системные функции, которые могут остановить процесс. исполнение.

Потоки в одном процессе разделяют:

  • инструкции по процессу
  • большинство данных
  • открытые файлы (дескрипторы)
  • сигналы и обработчики сигналов
  • текущий рабочий каталог
  • идентификатор пользователя и группы

Более подробную информацию можно найти здесь .

Napster_X
источник
2
У процесса может быть несколько потоков. Если один из потоков в процессе вызывает fork, имеет ли разветвленный процесс полностью дублированную память, но только вызывающий поток находится в новом процессе?
Michael
Ответ: ДА stackoverflow.com/questions/10080811/…
Майкл
30

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

Например, реализация потоковой передачи по умолчанию в Ruby не использует настоящие потоки ОС / ядра. Вместо этого он имитирует наличие нескольких потоков, переключаясь между объектами Thread в одном потоке / процессе ядра.

Это важно для многопроцессорных / многоядерных систем, потому что эти типы легких потоков могут работать только на одном ядре - вы не получите большого повышения производительности за счет наличия нескольких потоков.

Другое место, где это имеет значение, - это когда один поток блокирует (ожидает ввода-вывода или вызывает IOCTL драйвера), все потоки блокируются.

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

В отличие от этого, fork дает вам другой процесс, который запускается одновременно на другом физическом процессоре, пока выполняется исходный процесс. Некоторые люди считают IPC более подходящим для своего приложения, другие предпочитают многопоточность.

Удачи и приятного времяпровождения! Многопоточность одновременно сложна и полезна.

Сэм Пост
источник
8
+1 за удар по нервам: «не все потоки дают вам настоящую многопроцессорность»
Dacav
5

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

Серджио
источник