Send traits and Sync traits

After the first few sections, we have covered the basic use of concurrency. One last point is that we allow ownership of data to be transferred to a thread after it is created (e.g. I32, String, Vec<T>, Arc<T>, etc.), but not all data can be transferred. For example, we reported an error when we tried to transfer Rc<T> ownership to the thread earlier:

use std::rc::Rc;
use std::thread;

let a = Rc::new(1);
let a2 = a.clone();
thread::spawn(|| {
  a2; Rc
      
        cannot be safely sent between threads
      
});
Copy the code

The truth is that Rc<T> does not Send the trait, which most rust types implement.

Send Traits allow ownership to be transferred between threads

Only types that implement the Send Trait can safely transfer ownership between threads, and with the exception of a few such as Rc<T>, almost all Rust types implement the Send Trait.

If we transfer the ownership of the cloned Rc<T> value to another thread, it is possible for both threads to update the reference count at the same time and cause count errors.

Sync Trait allows simultaneous access by multiple threads

It is not enough to pass in the thread. We also need to be able to access the data in the thread. For example, Mutex<T> can be accessed in the thread, but RefCell<T> cannot:

use std::cell::RefCell;
use std::thread;

let a = RefCell::new(1);
thread::spawn(|| {
  a.borrow_mut(); RefCell
      
        cannot be shared safely between threads
      
});
Copy the code

Only types that implement the Sync trait can be safely referenced by multiple threads. The type Mutex<T> is Sync and can be shared by multiple threads. The type RefCell<T> does not satisfy the Sync constraint.

Manually implementing Send and Sync is not safe

When a type consists entirely of types that implement Send and Sync, it automatically implements Send and Sync.

We don’t need to manually implement related traits for this type. These two traits, called “tag traits,” Send and Sync, don’t actually have any implementation methods. They are used only to identify concurrency-related immutability.