Menu

Локальное хранилище потока

Класс хранения 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, которую все потоки
// могут читать и, что особенно опасно,
// изменять!

Подробнее

rdmd playground.d