Статические переменные C и форк Linux

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


person eat_a_lemon    schedule 02.02.2011    source источник


Ответы (4)


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

person zwol    schedule 02.02.2011
comment
Я работаю с примерно 10 МБ оперативной памяти, и я не вижу, как объем свободной памяти падает после вызова форка? Если статическое распределение происходит во время компиляции, то как форк может его дублировать? - person eat_a_lemon; 02.02.2011
comment
статическое распределение не происходит во время компиляции - это происходит во время выполнения, реализация которого остается за рассматриваемой библиотекой C, но это должно быть сделано до main. Таким образом, эта память является частью образа процесса, который дублирует fork. - person ; 02.02.2011
comment
@juxtapose: когда вы fork() программы, все, что происходит, это то, что память, используемая программой, помечается копией при записи. Таким образом, использование вашей оперативной памяти не начнет увеличиваться, пока вы не начнете писать в память, а затем только страницы, которые вы написали, останутся нераспределенными. - person btilly; 02.02.2011

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

person Nikolai Fetissov    schedule 02.02.2011

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

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

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

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

person Community    schedule 02.02.2011

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

person Maciej    schedule 02.02.2011