Box, Rc, Arc, and the relation with threads.

Box, Rc, Arc, and the relation with threads.

This is a learning journal, so content here is compressed with the main points, mainly.

The Threads

Working with threads in traditional programming languages requires some cares about the shared memory. A problem can occur when one or more threads changes a shared data at the same time, raising a racing error.

Rust works in a called thread-safe mode, it does not share data between the threads and just allows thread-safe operations. It seems something like an ownership strategy that prevents memory errors also makes it possible to write safe concurrent programs.

Before dive into the main point of the Blog, some topics need to be overviewed to construct a progressive understatement of the content.

What is Box<T>?

Box is, basically, a non-copyable pointer’s type with a defined size in the stack to a type generic T in the heap. A Box can be used to:

  • When is needing to know the type’ size in compile time

  • When is required to transfer ownership of a broad amount of data, and it can’t be copied

  • When must know whether a type implements a private trait.

  • And so on…

The Rust’s compiler has to know the size of the things at compile time, so defining a struct with a variable size can be a problem for the compiler. To solve this, it is necessary to wrap the problematic type in a Box, that has a fixed type in Stack, it will point to a heap, as so can grow freely.

The Stack in Rust has a limit of memory of 2MB, and is settled at compile time.

In this example, the block encapsulates other blocks within itself, making the definition of total blockchain size impossible to do. This is for the fact of the blockchains can contain ’n’ blocks.

enum Blockchain {
    Block(u32, Box<Blockchain>),

use Blockchain::{Block, End};

fn main() {
    let blockchain = Block(0, 

What is Rc<T>?

Rc stands for reference counting, and it is used in Rust to makes possibles a single value has multiples owners. The behavior of Rc is, as the name says, keeps track of the number of references to a value, which determines whether a value is still in use. In case the reference’s number is zero, the value can be freely.

It is important to say that Rc is “single thread”

This example is similar to the other, however in this one, the main blockchain transfers its ownership to others.

use std::rc::Rc;

enum Blockchain {
    Block(u32, Rc<Blockchain>),

use Blockchain::{Block, End};

fn main() {
    let blockchain_main = Rc::new(Block(0, Rc::new(Block(1, Rc::new(Block(2, Rc::new(End)))))));

    let blockchain_a = Block(10, Rc::clone(&blockchain_main));
    let blockchain_b = Block(100, Rc

What is Arc<T>?

Arc is a type from the std::sync submodule, and with it is possible to handle shared mutable state through threads. Arc stands for Atomic Reference Counting, it is like the Rc, Reference Counting, previously seen, but with the possibility to work with threads.

Thanks for @amiguxo for give me a hand to understand this.

The following example gets the blockchain created in the main function and clone it to each thread spawned, thereafter, each one creates itself blockchain based on the main one.

use std::thread;
use std::sync::Arc;
enum Blockchain {
    Block(u32, Arc<Blockchain>),

use Blockchain::{Block, End};

fn main() {
    let blockchain = Arc::new(

    for t in 3..10 {
        let clone = blockchain.clone();
        thread::spawn(move || {
            let _blockchain_thread = Block(t, clone);

As a said in the beginner, this is my diary of learning about this topic, so some information can be too compressed, but I think it can be useful to someone.

Thanks for reading, and you are welcome to share, comment or correct me.

Did you find this article valuable?

Support Henry Barreto by becoming a sponsor. Any amount is appreciated!