#thread-local #thread-id #thread

no-std thid

No-std, no-alloc thread IDs and thread-locals

3 releases

Uses new Rust 2024

0.0.3 Nov 22, 2025
0.0.2 Nov 4, 2025
0.0.1 Sep 14, 2025

#905 in Concurrency


Used in 6 crates (3 directly)

MIT license

13KB
256 lines

thid

No-std, no-alloc thread IDs and thread-locals.

no_std is only supported on nightly until thread_local is stabilized.

License

MIT


lib.rs:

A no_std-compatible implementation of thread IDs and owned thread-local objects.

Thread IDs are lazily initialized upon first access and can be accessed via:

let current_thread_id = thid::ThreadId::current();

Thread-local objects can be created and passed around as follows:

use std::{cell::RefCell, sync::Arc};

let local_object = Arc::new(thid::ThreadLocal::<RefCell<String>>::new());

let t1 = std::thread::spawn({
    let local_object = local_object.clone();
    move || {
        let local_value = local_object.get_or(|| RefCell::new("foo".into()));
        *local_value.borrow_mut() += "bar";
    }
});
let t2 = std::thread::spawn({
    let local_object = local_object.clone();
    move || {
        let local_value = local_object.get_or(|| RefCell::new("baz".into()));
        *local_value.borrow_mut() += "bip";
    }
});

t1.join().unwrap();
t2.join().unwrap();

let mut local_object = Arc::into_inner(local_object).expect("one remaining reference");
for mut_value in local_object.iter_mut() {
    let mut_value = mut_value.get_mut();
    *mut_value += "new";
}

let collected = local_object.iter_mut().map(|s| s.borrow().clone()).collect::<Vec<_>>();
assert_eq!(collected.len(), 2);
assert!(collected.contains(&"foobarnew".into()));
assert!(collected.contains(&"bazbipnew".into()));

No runtime deps