Data Races — Atomic Rust.

A Problem With Reference Counters And Multi-Threaded Rust.

Verus Novem
2 min readOct 20, 2024

Data Race

A data race occurs in multi-threaded programming when two or more threads access shared data at the same time, and at least one of the accesses is a write.

Without proper synchronization, this can lead to unpredictable behavior such as corrupted data, crashes (panics in rust), lost updates, etc.

Reference Counter

Rust’s built-in Reference Counter (std::rc::Rc) allows us to make multiple references to a single piece of data.

You could store an array inside an Rc<T>, clone it, and call the get pointer method on both the original and clone and you will get same pointer each time.

use std::rc::Rc;

let a = Rc::new([1, 2, 3]);
let b = a.clone();

assert_eq!(a.as_ptr(), b.as_ptr()); // Same allocation!

Now, this code above will work perfectly fine given that both the original and cloned data is accessed within the same thread.

But, would it work when we try to access it across a different thread? Unfortunately no, It won’t.

  | error[E0277]: `Rc` cannot be sent between threads safely
8 |
| thread::spawn(move || dbg!(b));

This error occurs because Rc<T> does not implement the Send trait, which is required to move data between threads. Rc<T> is designed for single-threaded scenarios only.

Atomic Reference Counter

One solution is to use an atomic reference counter, Arc<T>, instead of Rc<T>.

Arc<T> is thread-safe because it performs reference count modifications using atomic operations, ensuring that access across threads is safe.

The term Atomic in programming refers to something related to threads or concurrency.

use std::sync::Arc;
use std::thread;

let a = Arc::new([1, 2, 3]);
let b = a.clone();

thread::spawn(move || dbg!(a));
thread::spawn(move || dbg!(b));

Conclusion

In summary, both Rc<T> and Arc<T> in the Rust standard library are designed to prevent data races, given that they’re used with a Mutex<T>. The Arc-Mutex does this by making sure there is only one mutable reference at once.

Sign up to discover human stories that deepen your understanding of the world.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Verus Novem
Verus Novem

Written by Verus Novem

A Self-taught programmer who'll teach you a thing or two about computers and technology. Not selling anything, just educating people.

Responses (2)

Write a response

you will get same pointer each time

Thank you for this.
Cloning is often used with Rc<T> and Arc<T> but tutorials don't always remind beginners that clones likely point to the same "object".

The Arc doesn’t prevent data races - it gives you an opportunity to create them! The Mutex (or RwLock), often used in conjunction with Arc, provide the mechanism to prevent data races.