Передача повідомлень

Замість того, щоб мати справу з потоками і синхронізацією, мова D дозволяє використовувати передачу повідомлень для задіяння потужності кількох ядер. Потоки використовуються для передачі повідомлень, тобто довільних значень. Таким чином, немає навмисного розподілу даних, що дозволяє уникнути типових проблем багатопоточності.

Усі функції, які реалізують передачу повідомлень у мові D, можуть бути знайдені у модулі std.concurrency. spawn створює новий потік оснований на визначеній користувачем функції:

auto threadId = spawn(&foo, thisTid);

thisTid є вбудованою функцією std.concurrency, яка посилається на існуючий потік, необхідний для передачі повідомлень. spawn виконує функцію, яку потрібно вказати як перший параметер, а додаткові параметри цієї функції виступають в якості додаткових аргументів.

void foo(Tid parentTid) {
    receive(
      (int i) { writeln("Значення ", i, " було відправлене!"); }
    );
    
    send(parentTid, "Готово");
}

Будучи подібною до функції switch-case, функція receive передає значення, отримані з інших потоків до потрібних делегатів (delegates) у залежності від типу отриманого значення.

Для того, щоб відправити повідомлення до певного потоку, необхідно застосувати функцію send разом з її id:

send(threadId, 42);

receiveOnly може бути використаний для отримання повідомлення певного виду:

string text = receiveOnly!string();
assert(text == "Готово");

Функції родини receive блокуються доти, доки певні дані не відправляться до поштової скриньки потоку.

Поглиблення

rdmd playground.d