Clause
← Уся документація

Перекладено з англійського оригіналу · 06042fa · 2026-10-09 · Читати англійською

Процеси

План 11, крок 43 (2026-10-08): запущені процеси на кооперативному виконавці (executor); крок 44: причини виходу й звіти про помилки; крок 45: надсилання повідомлень; крок 46: вибіркове отримання (selective receive); крок 47: тайм-аути receive; крок 48: зв'язки (links) і сигнали виходу; крок 49: монітори; крок 50: зареєстровані імена; крок 53: порти (жодних); крок 56: робочі потоки планувальника; крок 57: пробудження між робочими потоками й завершення роботи.

Виконавець

Один runtime виконує свої процеси на своїх робочих потоках планувальника (робочі потоки, модель виконання). Під час запуску виклик вхідної функції стає першим процесом, головним процесом, і виконавець працює, доки той не завершиться:

Робочі потоки

Крок плану 56 (2026-10-08). Виконавець виконує процеси на RuntimeOptions::schedulers робочих потоках: потоці, що запустив програму, і ще одному потоці на кожен додатковий робочий потік. Програми беруть кількість із --schedulers N (від 1 до 1 024, опції runtime); типово — один робочий потік на логічний процесор, як +S в OTP.

Пробудження й завершення роботи (крок плану 57) не потребують додаткового механізму, бо кожна зміна стану планування процесу відбувається під м'ютексом виконавця:

Виходи

Процес, відмінний від головного, завершується з причиною виходу, як в OTP (detail::exit_reason, process/exits). Сигнали виходу передають її зв'язаним процесам (зв'язки), а повідомлення 'DOWN' — процесам-моніторам (монітори); звіти про помилки показують її.

Як завершується процесПричина виходуЗвіт про помилку
Його перший виклик повертає значенняnormalНемає
exit(Reason) (також normal, kill)ReasonНемає
Помилка (error/1,2,3, badarith, {badmatch, V}, undef, ...){Reason, Stack}Так
Неперехоплений throw(Value){{nocatch, Value}, Stack}Так
Його завершує сигнал виходу (сигнали виходу)Причина сигналу, killed для exit(Pid, kill)Немає

Звіт про помилку пишеться в stderr, коли процес завершується, після скидання стандартного виводу, у форматі типового обробника журналу (logger) OTP:

=ERROR REPORT==== 8-Oct-2026::03:42:15.983000 ===
Error in process <0.8.0> with exit value:
{boom,[{crash_reports,'-main/1-fun-6-',0,[]}]}

Заголовок містить місцевий час; причина розкладається так, як це робить ~p. Головний процес такого звіту не пише: його неперехоплений виняток є винятком програми (виконувані файли).

Повідомлення

Dest ! Msg і erlang:send(Dest, Msg) (крок плану 45) спершу обчислюють Dest і повертають Msg.

DestЕфект
pid живого процесуMsg копіюється в купу отримувача (копіювання між купами) зі збереженням спільних частин і додається до його вхідної черги сигналів
pid процесу, що завершивсяНічого; надсилання успішне
Зареєстроване ім'яЯк для його pid; badarg, коли жоден живий процес не має цього імені
{Name, nonode@nohost} із двох атомівЯк для pid, зареєстрованого як Name; нічого, коли такого немає
{Name, Node} для будь-якого іншого вузлаНічого (інших вузлів немає)
Будь-що іншеbadarg

Receive

receive (кроки плану 46–47) обирає серед своїх клауз, як case, над повідомленнями поштової скриньки:

Крок плану 48. Зв'язок з'єднує два процеси в обох напрямках (Signals у кожному контексті: зв'язані pid у порядку створення зв'язків і прапорець trap_exit).

Монітори

Крок плану 49. Монітор односпрямований: процес-монітор тримає його (за посиланням, у Signals), а процес під монітором зберігає посилання й pid монітора, щоб надіслати повідомлення, коли завершиться.

Зареєстровані імена

Крок плану 50. Виконавець тримає одну таблицю імен (атомів) до pid, а кожен процес — власне ім'я (Signals::name).

Сигнали виходу

Кожен сигнал виходу надходить від процесу, що виконується (exit/2, exit_signal/2, link/1), або від завершення процесу. Виконавець обробляє його одразу, коли його ціль не виконується на іншому робочому потоці, інакше — щойно квант цілі закінчився (робочі потоки, scheduler/signals): завершена ціль залишає чергу виконання чи своє очікування і доводиться до завершення (сигнали її зв'язкам надіслано, звіт про помилку записано, контекст звільнено) до того, як вбудована функція надсилання поверне керування. Довгий зв'язаний ланцюг завершується процес за процесом без рекурсії.

Сигнал процесуБез перехоплення виходівЗ перехопленням виходів
exit(Pid, kill), exit_signal(Pid, kill)Завершується з причиною killedЗавершується з причиною killed
Причина normal (від зв'язку або надіслана іншому процесу)НічогоПовідомлення {'EXIT', From, normal}
exit(self(), normal)Завершується з причиною normal (особливість OTP)Повідомлення {'EXIT', Self, normal}
exit_signal(self(), normal)НічогоПовідомлення {'EXIT', Self, normal}
Будь-яка інша причина, включно з kill від зв'язкуЗавершується з цією причиноюПовідомлення {'EXIT', From, Reason}

Порти

Порти (кроки плану 57A–57F) описано в портах: порт зв'язаний із процесом, що його відкрив, бере участь у зв'язках, моніторах, сигналах виходу й зареєстрованих іменах, як процес, і спілкується зі своїм під'єднаним процесом повідомленнями. Крок 57B надає ідентичності, таблицю портів, вбудовані функції портів і порти {fd, In, Out} лише для виводу.

Вбудовані функції

Вбудована функціяПоведінка
spawn(Fun)badarg, якщо Fun не fun; інакше новий процес викликає Fun(), породжуючи в цьому процесі {badarity, {Fun, []}} для іншої арності
spawn(M, F, Args)badarg, якщо M і F не атоми або Args не правильний список; інакше новий процес викликає M:F(Args...), породжуючи в цьому процесі undef, коли жоден модуль її не експортує і немає вбудованої функції з таким ім'ям
spawn_link(Fun), spawn_link(M, F, Args)Як spawn, і новий процес зв'язується з тим, хто викликає (зв'язки)
is_process_alive(Pid)badarg, якщо Pid не pid; true, доки його процес не завершився
spawn_monitor(Fun), spawn_monitor(M, F, Args)Як spawn, повертаючи {Pid, Ref} нового монітора
link(Pid), unlink(Pid)badarg, якщо Pid не pid (зв'язки)
monitor(process, Item)badarg для іншого типу чи елемента; посилання (монітори); Item — це pid або зареєстроване ім'я
register(Name, Pid), unregister(Name), whereis(Name), registered()Див. зареєстровані імена; Name має бути атомом
demonitor(Ref), demonitor(Ref, Options)badarg, якщо Ref не посилання або Options не правильний список із flush та info
exit(Dest, Reason), exit_signal(Dest, Reason)badarg, якщо Dest не pid і не посилання; true після сигналу виходу
process_flag(trap_exit, Bool)Попереднє значення; badarg для іншого прапорця чи не булевого значення
erlang:send(Dest, Msg), Dest ! MsgMsg після його надсилання (повідомлення); send/2 не імпортується автоматично

Новий процес стає в чергу за всіма готовими до виконання процесами; spawn одразу повертає його pid.