notes

Log | Files | Refs | README

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