I find that Rust-like rules (&T across threads and &mut T within a thread, restricting cross-thread mutation to &Mutex<T> and &AtomicT, global variables are treated as shared) are the best approach I've seen so far to general multithreading (as opposed to structured subsets like message passing or structured concurrency, which I haven't explored as much). However I'm unsure if mutexes are incompatible or unnecessary with the majority of single-core Arduinos with cooperative multitasking, and treating global data as shared is a pain on embedded and binding them to a specific thread is not a problem Rust has solved yet (you'll have to find your own solution).