Library`spawn/1`, `send/2`, `receive`

`spawn/1`, `send/2`, `receive`

Learn about `spawn/1`, `send/2`, `receive` as part of Elixir Functional Programming and Distributed Systems

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:

code
spawn/1
,
code
send/2
, and
code
receive
.

Creating Processes with spawn/1

code
spawn/1
is the primary function for creating a new Elixir process. It takes a function as an argument and starts a new process to execute that function. Each process has a unique identifier, called a PID (Process Identifier), which is returned by
code
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.

What is the primary function used to create a new Elixir process, and what does it return?

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

code
send/2
function is used for this purpose. It takes a PID and a message as arguments. The message can be any Elixir term, such as atoms, tuples, lists, or maps.

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

code
receive
block is used to pattern match and retrieve messages from this mailbox. It's a blocking operation; if the mailbox is empty, the process will wait until a message arrives.

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

code
receive
within a loop to continuously process messages. You can define multiple patterns within a single
code
receive
block to handle different types of messages. The
code
after
clause provides a way to handle timeouts, preventing a process from waiting indefinitely.

What happens if a process encounters a 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

code
spawn/1
,
code
send/2
, and
code
receive
is foundational for building concurrent and distributed systems in Elixir. Remember that processes are isolated and communicate solely through message passing, which promotes fault tolerance and simplifies reasoning about concurrent execution.

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

Elixir - Processes(documentation)

The official Elixir documentation provides a concise overview of processes, including `spawn`, `send`, and `receive`.

Elixir School - Processes(tutorial)

A beginner-friendly tutorial that explains the core concepts of Elixir processes with practical examples.

Learn You Some Erlang for Great Good! - Processes(tutorial)

While for Erlang, this chapter covers the fundamental concepts of processes and message passing, which are directly applicable to Elixir.

Elixir in Action: Concurrency(blog)

This book excerpt (often available as a free sample) delves into Elixir's concurrency model, explaining `spawn`, `send`, and `receive` in depth.

Understanding Elixir Processes(video)

A video explanation that visually breaks down how Elixir processes work and communicate.

Elixir's Actor Model Explained(video)

This video explains the actor model, which is the foundation of Elixir's concurrency, and how `spawn`, `send`, and `receive` fit into it.

Elixir's send/receive mechanism(blog)

A Reddit discussion that offers insights and practical tips on using `send` and `receive` effectively.

Process-based concurrency in Elixir(documentation)

An excerpt from the 'Elixir in Action' book, focusing on the practical application of processes for concurrency.

Erlang/OTP Documentation - Processes(documentation)

The foundational Erlang documentation on processes, which Elixir builds upon. Essential for understanding the underlying VM behavior.

Elixir's `spawn` function(documentation)

The official Hexdocs for the `spawn/1` function, detailing its signature and behavior.