Degen Code

Degen Code

Rust For Pythonistas

Part IV: Threading & Concurrency

Sep 29, 2025
∙ Paid
Share

The Rust Book devotes a chapter to what it calls “Fearless Concurrency”.

If you’ve done concurrent programming using coroutines, threads, or multiple processes, you know how difficult it can be. You must balance protection from data races and corruption against the risk of deadlock and slowdown.

The Rust promise is that the ownership model mitigates the impact of both: the former because simultaneous read/write issues are prohibited; the latter because locks become mostly unnecessary for common concurrency patterns.

We will study how to spawn threads in Rust, the Arc and Mutex synchronization primitives, the Sync and Send traits, parallel iteration using Rayon, and async functions using Tokio.

Threads

Rust offers threading support through the standard library. This example from the book can be copied directly into Playground and executed:

use std::thread;
use std::time::Duration;

fn main() {
    thread::spawn(|| {
        for i in 1..10 {
            println!(”hi number {i} from the spawned thread!”);
            thread::sleep(Duration::from_millis(1));
        }
    });

    for i in 1..5 {
        println!(”hi number {i} from the main thread!”);
        thread::sleep(Duration::from_millis(1));
    }
}

Closures

The only thing new here is the strange argument to spawn, which we will review briefly.

Rust allows for anonymous functions that can capture the values of variables outside their scope at runtime. Python’s lambda is similar.

In the example above, the closure takes this form:

|| {
    for i in 1..10 {
        println!(”hi number {i} from the spawned thread!”);
        thread::sleep(Duration::from_millis(1));
    }
}

The || is where the inputs to the closure are placed. Since this closure doesn’t take any input, it is empty. The actions of the closure are defined just like any other function, including the curly braces.

If you wanted to be more explicit, you can assign the closure to a variable:

let spawned_hi = || {
    for i in 1..10 {
        println!(”hi number {i} from the spawned thread!”);
        thread::sleep(Duration::from_millis(1));
    }
};

Which you can call like a standard function::

spawned_hi();

Or pass it to the thread:

thread::spawn(spawned_hi);

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2025 BowTiedDevil
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture