Elixir-prosesser og meldingsutveksling
Lær om lette Elixir-prosesser, hvordan de kommuniserer og prinsippene for «share nothing»-samtidighet.
Elixir-prosesser og meldingsutveksling er en gratis leksjon i Elixir og Phoenix: Skalerbar backendutvikling på CoddyKit. Dette er leksjon 1 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Elixir og Phoenix: Skalerbar backendutvikling, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Elixir og Phoenix: Skalerbar backendutvikling inneholder totalt 4 leksjoner.
Bli kjent med Elixir-prosesser
Elixir er laget for samtidighet, og prosesser er de grunnleggende byggesteinene. Tenk på dem som små, isolerte programmer som kjører samtidig.
I motsetning til prosesser eller tråder i operativsystemet er Elixir-prosesser svært lette. Du kan ha hundretusener, ja til og med millioner, kjørende på én enkelt maskin!
- Isolasjon: Hver prosess har sitt eget minne.
- Kommunikasjon: De kommuniserer med hverandre ved å sende meldinger.
- Feiltoleranse: Hvis én krasjer, tar den ikke ned de andre.
Opprette nye prosesser
Vi oppretter en ny Elixir-prosess ved hjelp av funksjonen spawn. Den tar en funksjon (ofte en anonym funksjon) som den nye prosessen skal kjøre.
spawn returnerer en prosessidentifikator (PID), som fungerer som en adresse til den nye prosessen.
defmodule MyModule do
def greet do
IO.puts "Hello from a new process!"
end
def run do
# Spawn a new process that calls MyModule.greet()
pid = spawn(MyModule, :greet, [])
IO.puts "Spawned process with PID: #{inspect(pid)}"
end
end
MyModule.run()Forstå prosess-ID-er (PID-er)
En prosessidentifikator, eller PID, er en unik referanse til en Elixir-prosess. Det er slik du adresserer en bestemt prosess for å sende den meldinger.
Tenk på en PID som et telefonnummer til en person. Du ringer nummeret for å snakke med personen, og prosesser bruker PID-er til å kommunisere.
- Hver prosess har en unik PID.
- PID-er er avgjørende for meldingsutveksling.
- Du kan inspisere en PID for å se den interne representasjonen.
Finne din egen PID
Akkurat som du kan hente PID-en til en nyopprettet prosess, kan enhver prosess som kjører finne sin egen PID ved hjelp av funksjonen self().
Dette er avgjørende når en prosess må fortelle andre hvordan de skal sende meldinger tilbake til den.
defmodule PidDemo do
def show_self_pid do
IO.puts "My PID is: #{inspect(self())}"
end
def run do
IO.puts "Main process PID: #{inspect(self())}"
# Spawn a process to show its own PID
spawn(PidDemo, :show_self_pid, [])
:timer.sleep(100) # Give the spawned process time to run
end
end
PidDemo.run()Kommunisere med meldinger
Elixir-prosesser kommuniserer ved å sende og motta meldinger. Dette er kjernen i samtidighetsmodellen «share nothing».
Meldinger er enkle Elixir-termer (alle datatyper) som sendes fra én prosess til en annen prosess sin «postkasse».
send(pid, message): Leggermessagei postkassen til prosessen som identifiseres avpid.receive do ... end: Venter på meldinger i postkassen til den gjeldende prosessen.
Svare tilbake
La oss se hvordan en «klient»-prosess kan sende en melding til en «server»-prosess og motta et svar.
Serverprosessen bruker en receive-blokk til å vente på og behandle innkommende meldinger. Deretter sender den et svar tilbake til klientens PID.
defmodule EchoServer do
def loop do
receive do
{:echo, client_pid, message} ->
send(client_pid, {:reply, message})
loop() # Continue looping to receive more messages
end
end
end
defmodule Client do
def run do
# Start the server process
server_pid = spawn(EchoServer, :loop, [])
IO.puts "Echo server started with PID: #{inspect(server_pid)}"
# Send a message to the server, including our own PID for reply
send(server_pid, {:echo, self(), "Hello, server!"})
IO.puts "Client sent 'Hello, server!' to #{inspect(server_pid)}"
# Wait for a reply
receive do
{:reply, message} ->
IO.puts "Client received reply: '#{message}'"
end
end
end
Client.run()Hvorfor «share nothing» er viktig
Elixir-prosesser følger prinsippet «share nothing». Det betyr at prosesser ikke deler minne eller tilstand direkte.
I stedet kommuniserer de utelukkende gjennom meldingsutveksling. Dette designvalget gir betydelige fordeler:
- Isolasjon: Hindrer én prosess i å ødelegge dataene til en annen.
- Samtidighet: Gjør det enklere å forstå og skalere systemer på tvers av flere CPU-kjerner.
- Feiltoleranse: Et krasj i én prosess påvirker ikke de andre, noe som gjør systemene mer robuste.
Smart meldingshåndtering
receive-blokken er svært kraftig fordi den bruker Elixirs mønstergjenkjenning.
Du kan definere ulike klausuler i receive for å matche bestemte meldingsstrukturer, mens andre meldinger ignoreres til en match blir funnet.
defmodule SmartReceiver do
def loop do
receive do
{:greet, name} ->
IO.puts "Hello, #{name}!"
loop()
{:farewell, name} ->
IO.puts "Goodbye, #{name}!"
loop()
:quit ->
IO.puts "Receiver quitting."
_ -> # Catch-all for unmatched messages
IO.puts "Received an unknown message."
loop()
end
end
def run do
receiver_pid = spawn(SmartReceiver, :loop, [])
send(receiver_pid, {:greet, "Alice"})
send(receiver_pid, "Just a string")
send(receiver_pid, {:farewell, "Bob"})
send(receiver_pid, :quit)
:timer.sleep(100) # Give processes time to finish
end
end
SmartReceiver.run()Bevare tilstand med rekursjon
Ettersom prosesser ikke deler minne, hvordan opprettholder de tilstand? Ved hjelp av rekursjon!
En prosess sender den gjeldende tilstanden sin som et argument til seg selv når den kaller løkkefunksjonen på nytt. Dette skaper en uforanderlig, sekvensiell flyt av tilstandsendringer.
defmodule Counter do
def loop(count) do
receive do
:increment ->
IO.puts "Incrementing to #{count + 1}"
loop(count + 1)
:get_count ->
IO.puts "Current count: #{count}"
loop(count)
:stop ->
IO.puts "Counter stopped at #{count}"
end
end
def run do
counter_pid = spawn(Counter, :loop, [0])
send(counter_pid, :increment)
send(counter_pid, :increment)
send(counter_pid, :get_count)
send(counter_pid, :stop)
:timer.sleep(100)
end
end
Counter.run()Test: Prosesser og meldinger
Se på følgende Elixir-kode:
defmodule Quiz do
def server_loop do
receive do
{:ping, client_pid} ->
send(client_pid, :pong)
server_loop()
end
end
def client_action(server_pid) do
send(server_pid, {:ping, self()})
receive do
:pong ->
IO.puts "Received pong!"
_ ->
IO.puts "Received something else."
end
end
def run do
server_pid = spawn(Quiz, :server_loop, [])
client_action(server_pid)
end
end
Quiz.run()Hva blir skrevet ut i konsollen når Quiz.run() kjøres?
Dine første steg innen samtidighet
Gratulerer! Du har tatt et stort steg inn i Elixirs kraftige modell for samtidighet.
Her er en kort oppsummering av det vi har gått gjennom:
- Elixir-prosesser: Lette, isolerte enheter for kjøring.
- PID-er: Unike identifikatorer for prosesser, brukt til adressering.
spawnogself(): Funksjoner for å opprette prosesser og hente PID-ene deres.- Meldingsutveksling: Den viktigste måten prosesser kommuniserer på, ved hjelp av
sendogreceive. - «Del ingenting»: Prosesser deler ikke minne, noe som gir robuste og skalerbare systemer.
- Mønstergjenkjenning: Brukes i
receivefor å håndtere ulike meldingstyper. - Tilstand: Opprettholdes gjennom rekursive funksjonskall.
Disse grunnleggende konseptene danner fundamentet for å bygge svært samtidige og feiltolerante applikasjoner i Elixir!
Lær deg Elixir med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 12
- Leksjoner
- 48
Ofte stilte spørsmål
Er leksjonen «Elixir-prosesser og meldingsutveksling» gratis?
Ja – hele teksten i «Elixir-prosesser og meldingsutveksling» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Elixir og Phoenix: Skalerbar backendutvikling-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Elixir og Phoenix: Skalerbar backendutvikling inneholder totalt 4 leksjoner.
Hva lærer jeg i «Elixir-prosesser og meldingsutveksling»?
Lær om lette Elixir-prosesser, hvordan de kommuniserer og prinsippene for «share nothing»-samtidighet. Du øver på Elixir og Phoenix: Skalerbar backendutvikling med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Elixir og Phoenix: Skalerbar backendutvikling?
Ingen tidligere erfaring er nødvendig. Elixir og Phoenix: Skalerbar backendutvikling på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.
Hvor lang tid tar leksjonen «Elixir-prosesser og meldingsutveksling»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Elixir og Phoenix: Skalerbar backendutvikling-leksjonen?
Ja. Alle Elixir og Phoenix: Skalerbar backendutvikling-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Elixir-prosesser og meldingsutveksling
- Implementering av GenServer-atferd
- Supervisorer og applikasjonsstruktur
- Samtidig arbeid med Task og Agent