Concurrency with Processes: spawn, send, and receive
In Elixir, concurrency is achieved through lightweight processes that run independently and communicate by sending messages. This section dives into the fundamental building blocks for creating and interacting with these processes:
spawn/1
send/2
receive
Creating Processes with spawn/1
spawn/1
spawn/1
spawn/1 creates a new, independent process.
When you call spawn/1
with a function, Elixir starts a new process to run that function. This new process operates concurrently with the calling process.
The spawn/1
function is the gateway to creating Elixir processes. It accepts a function (or a {Module, :function, [args]}
tuple) and returns the PID of the newly created process. This process then executes the provided function in isolation. Think of it as launching a tiny, independent program within your Elixir application.
spawn/1
is used to create a new process, and it returns the Process Identifier (PID) of that new process.
Sending Messages with send/2
Processes communicate by sending messages to each other. The
send/2
send/2 is how processes exchange information.
To send data from one process to another, you use send(pid, message)
. The pid
is the identifier of the receiving process, and message
is the data being sent.
The send/2
function is asynchronous; it places the message into the mailbox of the target process and returns immediately. The sending process doesn't wait for the message to be processed. This non-blocking nature is crucial for maintaining concurrency and responsiveness.
Messages are immutable in Elixir. When a message is sent, a copy is made, ensuring that modifications to the message in one process do not affect the original in another.
Receiving Messages with receive
Processes have a mailbox where incoming messages are stored. The
receive
The receive
block in Elixir allows a process to inspect its mailbox and act upon messages that match specific patterns. It's structured with do:
and ->
for each pattern. The after:
clause is optional and specifies a timeout, after which a different action can be taken if no matching message arrives. This mechanism is fundamental for stateful processes that react to external events or commands.
Text-based content
Library pages focus on text content
A common pattern is to use
receive
receive
after
receive
block and its mailbox is empty?The process will block and wait until a message arrives in its mailbox.
Putting It All Together: A Simple Example
Let's consider a simple scenario where one process sends a greeting to another. The receiving process will then print the greeting.
Loading diagram...
This illustrates the basic flow: one process (A) creates another (implicitly or explicitly), sends a message to its PID, and the receiving process (B) waits for and processes that message.
Key Concepts and Best Practices
Understanding
spawn/1
send/2
receive
Elixir processes are not OS threads. They are much lighter, with thousands or even millions able to run on a single OS thread, managed by the Erlang VM (BEAM).
Learning Resources
The official Elixir documentation provides a concise overview of processes, including `spawn`, `send`, and `receive`.
A beginner-friendly tutorial that explains the core concepts of Elixir processes with practical examples.
While for Erlang, this chapter covers the fundamental concepts of processes and message passing, which are directly applicable to Elixir.
This book excerpt (often available as a free sample) delves into Elixir's concurrency model, explaining `spawn`, `send`, and `receive` in depth.
A video explanation that visually breaks down how Elixir processes work and communicate.
This video explains the actor model, which is the foundation of Elixir's concurrency, and how `spawn`, `send`, and `receive` fit into it.
A Reddit discussion that offers insights and practical tips on using `send` and `receive` effectively.
An excerpt from the 'Elixir in Action' book, focusing on the practical application of processes for concurrency.
The foundational Erlang documentation on processes, which Elixir builds upon. Essential for understanding the underlying VM behavior.
The official Hexdocs for the `spawn/1` function, detailing its signature and behavior.