Clause
← All dokumentation

Översatt från det engelska originalet · 1e3a39c8-dirty · 2026-10-26 · Läs på engelska

Processer

Exekutor

En runtime kör sina processer på sina schemaläggares arbetstrådar (arbetstrådar, exekveringsmodell). Vid uppstart görs anropet av ingångsfunktionen till den första processen, huvudprocessen, och exekutorn körs tills den avslutas:

Arbetstrådar

Exekutorn kör processer på RuntimeOptions::schedulers arbetstrådar: tråden som startade programmet och ytterligare en tråd per extra arbetstråd. Program tar antalet från --schedulers N (1 till 1 024, runtime-alternativ); standardvärdet är en arbetstråd per logisk processor som programmet får köras på (dess affinitetsmask, som OTP:s onlineschemaläggare), eller per CPU i --scheduler-cpus.

Väckningar och nedstängning behöver ingen ytterligare mekanism, eftersom varje ändring av en process schemaläggningstillstånd sker under exekutorns mutex:

CPU-bindning

Arbetstrådar är obundna som standard: operativsystemet placerar dem på valfri CPU i programmets affinitetsmask, som OTP:s standard +sbt u. --scheduler-cpus SET (runtime-alternativ) binder arbetstråd N till mängdens N:te CPU, i turordning med omstart när det finns fler arbetstrådar, som OTP:s +sbt/+sct; timer- och I/O-trådarna förblir obundna.

Tidsgränser för receive

Timrar ligger i ett hierarkiskt hashat timerhjul, så som ERTS håller dem (scheduler/timer_wheel):

Avslut

En annan process än huvudprocessen avslutas med en exitorsak, som i OTP (detail::exit_reason, process/exits). Exitsignaler bär den till länkade processer (länkar) och 'DOWN'-meddelanden till övervakande (monitorer); felrapporter visar den.

Hur processen avslutasExitorsakFelrapport
Dess första anrop returnerarnormalIngen
exit(Reason) (även normal, kill)ReasonIngen
Ett fel (error/1,2,3, badarith, {badmatch, V}, undef, ...){Reason, Stack}Ja
Ett ofångat throw(Value){{nocatch, Value}, Stack}Ja
En exitsignal avslutar den (exitsignaler)Signalens orsak, killed för exit(Pid, kill)Ingen

En felrapport skrivs på stderr när processen avslutas, efter att standard-utdata har tömts, i formatet för OTP:s standardhanterare för loggning:

=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,[]}]}

Huvudet innehåller lokal tid; orsaken formateras som ~p gör. Huvudprocessen skriver ingen: dess ofångade undantag är programmets (körbara filer).

Meddelanden

Dest ! Msg och erlang:send(Dest, Msg) evaluerar Dest först och returnerar Msg.

DestEffekt
En pid för en levande processMsg kopieras platt in i mottagarens heap (kopiering mellan heapar), så som OTP kopierar meddelanden, ett stort meddelande in i ett block som mottagaren tar över (överlämning av meddelanden), och läggs till sist i dess signalinkorg; till en mottagare som körs på en annan arbetstråd, in i en buffert bland dess ankomster som den tar nästa gång den tittar (ankomstbuffertar)
En pid för en process som har avslutatsIngenting; sändningen lyckas
Ett registrerat namnSom för dess pid; badarg när ingen levande process har namnet
{Name, nonode@nohost} av två atomerSom för den pid som är registrerad som Name; ingenting när det inte finns någon
{Name, Node} för någon annan nodIngenting (det finns inga andra noder)
En referensSom för ägaren till ett aktivt alias; annars ingenting
Allt annatbadarg

Ankomstbuffertar

En sändning till en process som körs på en annan arbetstråd tar inget lås alls (skapande och nedmontering av processer):

Receive

receive väljer bland sina klausuler som case, över meddelandena i brevlådan:

En länk förbinder två processer i båda riktningarna (Signals i varje kontext: de länkade pid:arna i länkordning och flaggan trap_exit).

Monitorer

En monitor är enkelriktad: den övervakande processen håller den (via referens, i Signals) och den övervakade processen behåller referensen och den övervakande pid:en, så att den kan skicka meddelandet när den avslutas.

Registrerade namn

Exekutorn har en tabell från namn (atomer) till pid:ar, och varje process sitt eget namn (Signals::name).

Processlexikon

put/2, get/0,1, get_keys/0,1 och erase/0,1 beter sig som OTP:s: put/2 och erase/1 returnerar det tidigare värdet eller undefined, erase/0 returnerar varje {Key, Value} och tömmer lexikonet, nycklar matchas med exakt likhet (1 och 1.0 är två nycklar).

Timrar

start_timer/3,4 och send_after/3,4 (builtins/erlang/timers.cpp, scheduler/timers.cpp) aktiverar en timer i exekutorns hjul (det som tidsgränser för receive använder) som skickar Msg, eller {timeout, TimerRef, Msg}, till en pid eller ett registrerat namn när den utlöses.

Introspektion

process_info/1,2 (builtins/erlang/introspection.cpp, scheduler/introspection.cpp) läser en annan process under exekutorns lås och kopierar dess termer (meddelanden, lexikon) till anroparens heap; en process som körs på en annan arbetstråd läses när dess tidsskiva tar slut. En pid utan levande process ger undefined.

Spawn-alternativ

Källor: builtins/erlang/spawning.cpp, scheduler/aliases.cpp.

Alias

Ett alias är en referens som meddelanden kan skickas till (Alias ! Msg): alias/0,1 (explicit_unalias, eller reply för ett meddelande), eller en monitor skapad med {alias, explicit_unalias | demonitor | reply_demonitor} till monitor/3 (demonitor upphör med monitorn, reply_demonitor avslutar också monitorn vid dess första meddelande). unalias/1 avslutar ett alias hos anroparen. En sändning till en referens som inte är ett aktivt alias, eller vars ägare har avslutats, kastas. Ett svarsalias förbrukas först när dess meddelande levereras, efter eventuell väntan på en upptagen ägare. {tag, Tag} till monitor/3 ersätter 'DOWN' i monitormeddelandet; portmonitorer tar inga alternativ.

Noder

Ett Clause-program är en nod som inte är distribuerad, nonode@nohost, och svarar som en sådan OTP-nod (builtins/erlang/node.cpp): nodes/0 är [], nodes(this | known) [nonode@nohost], andra typer []; nodes/2 ger {nonode@nohost, #{connection_id => undefined, node_type => this}} för de efterfrågade nycklarna. is_alive/0 är false, monitor_node/2,3 ger error:notalive och disconnect_node/1 returnerar ignored.

Exitsignaler

Varje exitsignal kommer från en körande process (exit/2, exit_signal/2, link/1) eller från slutet av en process. Exekutorn hanterar den direkt när dess mål inte körs på en annan arbetstråd, annars när målets tidsskiva har tagit slut (arbetstrådar, scheduler/signals): ett avslutat mål lämnar körkön eller sin väntan och slutförs (dess länkar signaleras, dess felrapport skrivs, dess kontext frigörs) innan den sändande inbyggda funktionen returnerar. En lång länkad kedja avslutas process för process utan rekursion.

Signal till en processFångar inte exitsFångar exits
exit(Pid, kill), exit_signal(Pid, kill)Avslutas med orsaken killedAvslutas med orsaken killed
Orsaken normal (från en länk, eller skickad till en annan process)IngentingMeddelandet {'EXIT', From, normal}
exit(self(), normal)Avslutas med orsaken normal (OTP:s egenhet)Meddelandet {'EXIT', Self, normal}
exit_signal(self(), normal)IngentingMeddelandet {'EXIT', Self, normal}
Varje annan orsak, inklusive kill från en länkAvslutas med den orsakenMeddelandet {'EXIT', From, Reason}

Portar

Portar specificeras i portar: en port är länkad till den som öppnade den, deltar i länkar, monitorer, exitsignaler och registrerade namn som en process och kommunicerar med sin anslutna process via meddelanden.

Suspendering av processer

erlang:suspend_process/1,2 och erlang:resume_process/1 (scheduler/suspension.cpp): varje suspendering är ett kvarhållande av målet i exekutorn, så en suspenderad process körs igen först när varje suspendering från varje suspenderare har återupptagits; meddelanden och signaler når den fortfarande (en exitsignal avslutar den fortfarande), och process_info(Pid, status) rapporterar suspended. När en suspenderare avslutas återupptas dess suspenderingar. En synkron suspendering av en process som körs på en annan arbetstråd väntar tills dess tidsskiva tar slut; asynchronous returnerar direkt, {asynchronous, Tag} skickar också {Tag, suspended} till anroparen, och unless_suspending svarar false när anroparen redan suspenderar processen. Att suspendera eller återuppta anroparen själv, en avslutad process, ett värde som inte är en pid eller med felaktiga alternativ ger badarg, liksom att återuppta en process som anroparen inte suspenderar.

Inbyggda funktioner

Inbyggd funktionBeteende
spawn(Fun)badarg om inte Fun är en fun; annars anropar en ny process Fun() och kastar {badarity, {Fun, []}} i den processen för en annan aritet
spawn(M, F, Args)badarg om inte M och F är atomer och Args en äkta lista; annars anropar en ny process M:F(Args...) och kastar undef i den processen när ingen modul exporterar den och ingen inbyggd funktion har det namnet
spawn_link(Fun), spawn_link(M, F, Args)Som spawn, och den nya processen länkas till anroparen (länkar)
is_process_alive(Pid)badarg om inte Pid är en pid; sant så länge dess process inte har avslutats
spawn_monitor(Fun), spawn_monitor(M, F, Args)Som spawn, och returnerar {Pid, Ref} för en ny monitor
link(Pid), unlink(Pid)badarg om inte Pid är en pid (länkar)
monitor(process, Item)badarg för en annan typ eller ett annat objekt; en referens (monitorer); Item är en pid eller ett registrerat namn
register(Name, Pid), unregister(Name), whereis(Name), registered()Se registrerade namn; Name måste vara en atom
demonitor(Ref), demonitor(Ref, Options)badarg om inte Ref är en referens och Options en äkta lista av flush och info
exit(Dest, Reason), exit_signal(Dest, Reason)badarg om inte Dest är en pid eller referens; true efter exitsignalen
process_flag(trap_exit, Bool), process_flag(min_heap_size, N), process_flag(save_calls, N)Den tidigare inställningen; badarg för en annan flagga, ett icke-booleskt värde eller en negativ storlek eller en storlek som inte är ett heltal
erlang:send(Dest, Msg), Dest ! MsgMsg, efter att det har skickats (meddelanden); send/2 importeras inte automatiskt
spawn(Node, ...), spawn_link(Node, ...), spawn_monitor(Node, ...) (/2, /4)Denna nod (nonode@nohost): som utan Node. En annan nod: OTP:s oanvändbara pid för en nod som inte är vid liv, en process som avslutas direkt med orsaken noconnection, så att en länk eller monitor rapporterar noconnection; badarg för en nod som inte är en atom
erlang:send(Dest, Msg, Options)ok, eller noconnect för ett meddelande till en annan nod med alternativet noconnect; alternativen nosuspend, noconnect, priority (ett vanligt meddelande)
send_nosuspend(Dest, Msg), send_nosuspend(Dest, Msg, [noconnect])true; false för en annan nod med noconnect
link(Pid, Options), exit(Dest, Reason, Options), exit_signal(Dest, Reason, Options)Som utan alternativ; Options är [] eller [priority] (en vanlig signal)
process_flag(Pid, save_calls, N)Den tidigare inställningen för en annan process (0..10000); behålls, men Clause sparar inga anrop; andra flaggor ger badarg
processes_iterator(), processes_next(Iter)Iterera över de levande processerna: {Pid, Iter1} eller none; en process som startas under genomgången kan dyka upp
bump_reductions(N)true för ett icke-negativt heltal; Clause räknar inga reduktioner
erlang:suspend_process(Pid), erlang:suspend_process(Pid, Options), erlang:resume_process(Pid)Se suspendering av processer
erlang:process_display(Pid, backtrace)true efter att anropsstacken för den levande processen Pid skrivits på standard-fel, en Module:Function/Arity per rad, den aktuella funktionen först; badarg för en annan typ eller en process som har avslutats

Den nya processen läggs sist i förälderns arbetstråds kö (arbetstrådar); spawn returnerar dess pid direkt.