У мові D найкращим способом створити багатопоточність є
покладання на незмінні (immutable)
дані і синхронізування потоків,
використовуючи передачу повідомлень. Мова D має вбудовану підтримку
синхронізації примітивів, а також підтримку типу з ключовим
словом загальнодоступні (shared)
для позначення доступних з
кількох потоків об'єктів.
Ідентифікатор типу shared
дозволяє позначати змінні, які
використовуються різними потоками:
shared(int)* p = new int;
int* t = p; // ПОМИЛКА
Наприклад, std.concurrency.send
дозволяє відправляти незмінні
або
загальнодоступні
дані, а також копіювати повідомлення для відправки.
Загальнодоступні
дані є транзитними, відповідно, якщо класс
або
структура
позначені як shared
, всі їх члени будуть позначені
так само. Зверніть увагу, що змінні static
не є shared
за
замовчуванням і будуть реалізовані за допомогою
локальної пам'яті потоку (ЛПП), де кожен потік отримає власну змінну.
synchronized
блоки дозволяють повідомити компілятору, що
дана секція є критичною і має бути доступна лише для одного
потоку в один проміжок часу.
synchronized {
importStuff();
}
У межах класу
ці блоки можуть бути обмежені різними об'єктами
м'ютекс із synchronized(member1, member2)
для того, щоб обмежити
багатопоточність. Копмілятор D автоматично вставляє критичні секції.
Цілий клас також може бути позначений як synchronized
, у той же час,
компілятор повинен переконатися, що тільки один потік має доступ до
певної копії.
Атомарні операції на змінних shared
можуть бути реалізовані за
допомогою помічника core.atomic.atomicOp
:
shared int test = 5;
test.atomicOp!"+="(4);