#c #multithreading #memory-management
#c #многопоточность #управление памятью
Вопрос:
Если у меня есть переменная в файле вне функции, объявленной и инициализированной как таковая:
static int i = 42;
Где хранится переменная i
? Это раздел данных?
Если у меня есть переменная в файле вне функции, объявленная, но не инициализированная как таковая:
static int j;
Где хранится переменная j
? Это BSS?
Я предполагаю, что j по умолчанию будет инициализировано равным нулю, и что, если я позже сделаю:
j = 1;
Где j
теперь будут храниться?
Теперь к той части, которая меня действительно интересует: доступны ли статические переменные области действия файла для всех потоков?
Я спрашиваю, потому что, конечно, куча доступна для всех потоков, но у каждого потока есть свой собственный стек, и ранее я предполагал, что статические переменные области видимости файла помещаются в стек точно так же, как переменные, объявленные внутри функции.
Просто из любопытства — применяются ли те же правила хранения для статических переменных области действия файла также для глобальных переменных?
Комментарии:
1.
static int i = 42;
переходит в раздел данных (даже если объявлен внутри функции);static int j;
переходит в раздел bss и остается там даже после записи в (.bss похож . данные, просто не инициализированные, поэтому они не занимают места в исполняемом образе);const static int x = 42;
переходит в раздел rdata (.rdata похож . данные, просто недоступные для записи).
Ответ №1:
Теперь к той части, которая меня действительно интересует: доступны ли статические переменные области действия файла для всех потоков
Да, все потоки имеют доступ ко всему адресному пространству.
Что более интересно, так это то, что объектам не обязательно иметь статическое хранилище, как это i
и j
делается в вашем примере. Если у вас есть объект в стеке потока A и каким-то образом удается передать его адрес потоку B, B может получить к нему доступ без проблем.
применимы ли те же правила хранения для статических переменных области действия файла и для глобальных переменных?
Оба из них имеют то, что называется «статическим хранилищем». В контексте переменной, объявленной вне какой-либо функции static
, просто делает ее невидимой за пределами ее единицы преобразования.
Комментарии:
1. В C11 то, что происходит, если поток пытается получить доступ к переменной другого потока с автоматической продолжительностью хранения (через указатель), определяется реализацией. В POSIX и большинстве практичных систем это разрешено, как вы говорите.