C статические переменные и linux fork - PullRequest
8 голосов
/ 02 февраля 2011

Привет! Я создал серверную программу, которая разветвляет новый процесс после того, как он принимает соединение с сокетом. В программе определено несколько статически распределенных глобальных переменных. Мой вопрос: эти статические буферы выделяются дважды после разветвления? Или вилка только дублирует адресное пространство в куче и стеке вызовов?

Ответы [ 4 ]

10 голосов
/ 02 февраля 2011

Дублировано все адресное пространство, включая все глобальные переменные и текст программы.

6 голосов
/ 02 февраля 2011

Все адресное пространство «дублируется» в течение fork(2). Это часто делается с помощью copy-on-write , и есть больше подробностей о совместном использовании текста программы и библиотек, но это не имеет значения здесь. И родительский, и дочерний процессы получают собственную копию статических данных.

2 голосов
/ 02 февраля 2011

Linux использует механизм, называемый копирование при записи.Это в основном означает, что пока переменная не изменена, родительский и новый процесс совместно используют одну переменную.Но перед изменением переменной она копируется, и новый процесс использует копию.Это сделано из соображений производительности, а метод называется ленивой оптимизацией.Поэтому вам не стоит беспокоиться, что изменение переменной в одном процессе изменит ее в другом.

2 голосов
/ 02 февраля 2011

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

В static это ключевое слово означает (из ISO C99):

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

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

...