Копируются ли потоки при вызове fork? - PullRequest
31 голосов
/ 14 апреля 2020

Если у меня есть программа, работающая с потоками и вызывающая fork() в системе unix, скопированы ли потоки? Я знаю, что виртуальная память для текущего процесса копируется 1: 1, чтобы новый процесс порождался. Я знаю, что потоки имеют свой собственный стек в виртуальной памяти процесса. Таким образом, хотя бы стек потоков тоже должен быть скопирован. Тем не менее, я не знаю, есть ли что-то еще для потоков, которые не находятся в виртуальной памяти и, следовательно, НЕ копируются. Если нет, два процесса совместно используют потоки или они являются независимыми копиями?

Ответы [ 4 ]

29 голосов
/ 14 апреля 2020

Нет.

Темы не копируются на fork(). Спецификация POSIX гласит (подчеркнуло мое):

fork - создать новый процесс

Процесс должен быть создан с одним потоком . Если многопоточный процесс вызывает fork (), новый процесс должен содержать реплику вызывающего потока и всего его адресного пространства, возможно, включая состояния мьютексов и других ресурсов. Следовательно, чтобы избежать ошибок, дочерний процесс может выполнять только асинхронные операции c -signal-safe до тех пор, пока не будет вызвана одна из функций exe c.

Чтобы обойти эту проблему, существует функция pthread_atfork(), чтобы помочь.

7 голосов
/ 14 апреля 2020

man fork :

Дочерний процесс создается с одним потоком, который вызвал fork (). Все виртуальное адресное пространство родительского объекта реплицируется в дочернем, включая состояния мьютексов, переменных условий и других объектов pthreads; использование pthread_atfork (3) может быть полезно для решения проблем, которые это может вызвать.

4 голосов
/ 14 апреля 2020

Из Открытой группы базовых спецификаций, выпуск 7, выпуск 2018 года fork :

Процесс должен быть создан с одним потоком. Если многопоточный процесс вызывает fork () , новый процесс должен содержать копию вызывающего потока и всего его адресного пространства, возможно, включая состояния мьютексов и других ресурсов. Следовательно, чтобы избежать ошибок, дочерний процесс может выполнять только асинхронные операции c -signal-safe до тех пор, пока не будет вызвана одна из функций exe c.

Когда приложение вызывает fork () из обработчика сигнала и любого из обработчиков вилки, зарегистрированных pthread_atfork () , вызывает функцию, которая не является asyn c -signal-safe, поведение не определено.

0 голосов
/ 14 апреля 2020

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

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

...