Класс хранения static
позволяет объявлять объекты,
инициализируемые только один раз. Если строка с
объявлением исполняется повторно, инициализация
пропускается.
Каждый поток получает собственную копию
static
объекта (TLS - локальное хранилище потока)
и не может читать либо модифицировать объект другого
потока, несмотря на то, что имя переменной то же
самое. Таким образом, static
позволяет
объявлять объекты, хранящие глобальное состояние
для текущего потока.
Такой подход отличается от, к примеру, C/C++ или Java,
где static
означает "глобально для приложения",
что влечёт проблемы с синхронизацией в многопоточных
программах.
Значение, присваиваемое static
переменной,
должно быть вычислимо во время компиляции. Оно не должно
иметь зависимостей времени исполнения! Во время исполнения
инициализацию static
переменных можно производить
при помощи static this()
- единожды исполняемого
конструктора структур, классов и модулей.
static int b = 42;
// b инициализируется единожды!
// При работе нескольких потоков,
// каждому потоку достаётся "собственная"
// b, без помех со стороны других потоков.
В дополнение, для объявления "классической" глобальной
переменной, доступной для чтения и изменения всем
потокам, используется класс хранения __gshared
-
эквивалент static
в C.
Такое уродливое название - дружеское напоминание о
том, что использовать его нужно как можно реже.
__gshared int b = 50;
// Так же инициализируется единожды!
// Истинно глобальная b, которую все потоки
// могут читать и, что особенно опасно,
// изменять!