send_and_sync.md (3015B)
1 # Send and Sync 2 3 `Send` and `Sync` are both **marker traits** in Rust that govern thread safety, 4 but they address different aspects of how data crosses thread boundaries. 5 6 ## `Send`: Ownership Transfer 7 8 A type is `Send` if it is safe to **transfer ownership** of a value to another 9 thread. In other words, you can _move_ a `T` into a new thread. Most primitive 10 types (`i32`, `bool`), `String`, `Vec<T>`, and `Arc<T>` are `Send`. Types that 11 are **not** `Send` include:[^1][^6] 12 13 - `Rc<T>` — its reference count is non-atomic, so moving it to another thread 14 risks a data race on the count[^3] 15 - Raw pointers (`*const T`, `*mut T`) — no synchronization guarantees when 16 dereferenced across threads[^6] 17 18 ## `Sync`: Shared Reference Access 19 20 A type is `Sync` if it is safe for **multiple threads to hold shared 21 references** (`&T`) to it simultaneously. Formally, `T` is `Sync` if and only if 22 `&T` is `Send`. Types that are **not** `Sync` include:[^5][^1] 23 24 - `RefCell<T>` — its borrow-checking is not thread-safe (non-atomic interior 25 mutability)[^6] 26 - `Cell<T>` — same reason; mutable access is not synchronized[^8] 27 - Raw pointers[^6] 28 29 ## How They Relate 30 31 The two traits are closely intertwined — `Sync` is almost _defined in terms of_ 32 `Send`. A useful mental model:[^8] 33 34 | Trait | Asks… | Example: YES | Example: NO | 35 | :----- | :----------------------------------------------- | :---------------- | :---------------------- | 36 | `Send` | Can ownership move to another thread? | `Arc<Mutex<T>>` | `Rc<T>` | 37 | `Sync` | Can a shared `&T` be used from multiple threads? | `Mutex<T>`, `i32` | `RefCell<T>`, `Cell<T>` | 38 39 A type can be `Send` but not `Sync` (e.g., `Mutex<T>` where ownership transfers 40 are fine but concurrent `&T` access needs the lock), or `Sync` but not `Send` 41 (e.g., a `MutexGuard`, which can be shared but must be released on the 42 originating thread). Both traits are **automatically derived** by the compiler — 43 you only need to intervene when working with `unsafe` code or types that should 44 explicitly opt out.[^3][^8] 45 <span style="display:none">[^10][^2][^4][^7][^9]</span> 46 47 <div align="center">⁂</div> 48 49 [^1]: https://doc.rust-lang.org/nomicon/send-and-sync.html 50 51 [^2]: https://www.reddit.com/r/rust/comments/ctdkyr/understanding_sendsync/ 52 53 [^3]: https://blog.masteringbackend.com/rust-send-and-sync-in-simple-terms 54 55 [^4]: https://stackoverflow.com/questions/59428096/understanding-the-send-trait 56 57 [^5]: https://www.reddit.com/r/rust/comments/1csrbhf/understanding_send_trait_in_rust/ 58 59 [^6]: https://leapcell.io/blog/understanding-send-and-sync-in-rust-async-handlers 60 61 [^7]: https://masteringbackend.com/posts/rust-send-and-sync-in-simple-terms 62 63 [^8]: https://www.youtube.com/watch?v=yOezcP-XaIw 64 65 [^9]: https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/nomicon/send-and-sync.html 66 67 [^10]: https://doc.rust-lang.org/book/ch16-04-extensible-concurrency-sync-and-send.html