Skip to content

Instantly share code, notes, and snippets.

@0atman
Last active March 13, 2024 11:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0atman/7c72895ee3fa0487103c9220b81c266e to your computer and use it in GitHub Desktop.
Save 0atman/7c72895ee3fa0487103c9220b81c266e to your computer and use it in GitHub Desktop.
Unlike non-scoped threads, scoped threads can borrow non-'static data, as the scope guarantees all threads will be joined at the end of the scope.
use std::thread;
struct User {
age: u16,
}
fn simple_thread() {
let user = User { age: 30 };
// thread::spawn(|| &user); // can't borrow `user` as thread may outlive current function
thread::spawn(|| user); // can only move into thread, then it's gone.
// nope: println!("`user` is moved : {}", &user.age)
}
fn simple_scope() {
let user = User { age: 30 };
thread::scope(|s| {
s.spawn(|| &user);
});
println!(
"Because the scope is over, we can access `user` again: {}",
&user.age
)
}
fn complex_scope_with_named_threads() {
let mut a = vec![1, 2, 3];
let mut x = 0;
thread::scope(|s| {
thread::Builder::new()
.name("first".into())
.spawn_scoped(s, || {
println!(
"hello from the {:?} scoped thread",
thread::current().name()
);
// We can borrow `a` here.
dbg!(&a);
})
.unwrap();
thread::Builder::new()
.name("second".to_string())
.spawn_scoped(s, || {
println!(
"hello from the {:?} scoped thread",
thread::current().name()
);
// We can even mutably borrow `x` here,
// because no other threads are using it.
x += a[0] + a[2];
})
.unwrap();
println!("hello from the main thread");
});
// After the scope, we can modify and access our variables again:
a.push(4);
assert_eq!(x, a.len());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment