Shared Ownership and Reference Counting So far we’ve looked at transferring ownership of a value to a thread using a move closure (“Threads in Rust” on page 2) and borrowing data from longer-living parent threads (“Scoped Threads” on page 5). When sharing data between two threads where neither thread is guaranteed to outlive the other, neither of them can be the owner of that data. Any data shared between them will need to live as long as the longest living thread. Statics There are several ways to create something that’s not owned by a single thread. The simplest one is a static value, which is “owned” by the entire program, instead of an individual thread. In the following example, both threads can access X, but neither of them owns it: static X: [i32; 3] = [1, 2, 3]; Shared Ownership and Reference Counting | 7 thread::spawn(|| dbg!(&X)); thread::spawn(|| dbg!(&X)); A static item has a constant initializer, is never dropped, and already exists before the main function of the program even starts. Every thread can borrow it, since it’s guaranteed to always exist. Leaking Another way to share ownership is by leaking an allocation. Using Box::leak, one can release ownership of a Box, promising to never drop it. From that point on, the Box will live forever, without an owner, allowing it to be borrowed by any thread for as long as the program runs. let x: &'static [i32; 3] = Box::leak(Box::new([1, 2, 3])); thread::spawn(move || dbg!(x)); thread::spawn(move || dbg!(x)); The move closure might make it look like we’re moving ownership into the threads, but a closer look at the type of x reveals that we’re only giving the threads a reference to the data. References are Copy, meaning that when you “move” them, the original still exists, just like with an integer or boolean. Note how the 'static lifetime doesn’t mean that the value lived since the start of the program, but only that it lives to the end of the program. The past is simply not relevant. The downside of leaking a Box is that we’re leaking memory. We allocate something, but never drop and deallocate it. This can be fine if it happens only a limited number of times. But if we keep doing this, the program will slowly run out of memory. Reference Counting To make sure that shared data gets dropped and deallocated, we can’t completely give up its ownership. Instead, we can share ownership. By keeping track of the number of owners, we can make sure the value is dropped only when there are no owners left. The Rust standard library provides this functionality through the std::rc::Rc type, short for “reference counted.” It is very similar to a Box, except cloning it will not allocate anything new, but instead increment a counter stored next to the contained 8 | Chapter 1: Basics of Rust Concurrency value. Both the original and cloned Rc will refer to the same allocation; they share ownership. use std::rc::Rc; let a = Rc::new([1, 2, 3]); let b = a.clone(); assert_eq!(a.as_ptr(), b.as_ptr()); // Same allocation! Dropping an Rc will decrement the counter. Only the last Rc, which will see the counter drop to zero, will be the one dropping and deallocating the contained data. If we were to try to send an Rc to another thread, however, we would run into the following compiler error: error[E0277]: `Rc` cannot be sent between threads safely | 8 | thread::spawn(move || dbg!(b)); | ^^^^^^^^^^^^^^^ As it turns out, Rc is not thread safe (more on that in “Thread Safety: Send and Sync” on page 16). If multiple threads had an Rc to the same allocation, they might try to modify the reference counter at the same time, which can give unpredictable results. Instead, we can use std::sync::Arc, which stands for “atomically reference counted.” It’s identical to Rc, except it guarantees that modifications to the reference counter are indivisible atomic operations, making it safe to use it with multiple threads. (More on that in Chapter 2.) use std::sync::Arc; let a = Arc::new([1, 2, 3]); let b = a.clone(); thread::spawn(move || dbg!(a)); thread::spawn(move || dbg!(b)); We put an array in a new allocation together with a reference counter, which starts at one. Cloning the Arc increments the reference count to two and provides us with a second Arc to the same allocation. Both threads get their own Arc through which they can access the shared array. Both decrement the reference counter when they drop their Arc. The last thread to drop its Arc will see the counter drop to zero and will be the one to drop and deallocate the array. Shared Ownership and Reference Counting | 9 Naming Clones Having to give every clone of an Arc a different name can quickly make the code quite cluttered and hard to follow. While every clone of an Arc is a separate object, each clone represents the same shared value, which is not well reflected by naming each one differently. Rust allows (and encourages) you to shadow variables by defining a new variable with the same name. If you do that in the same scope, the original variable cannot be named anymore. But by opening a new scope, a statement like let a = a.clone(); can be used to reuse the same name within that scope, while leaving the original variable available outside the scope. By wrapping a closure in a new scope (with {}), we can clone variables before moving them into the closure, without having to rename them. let a = Arc::new([1, 2, 3]); let b = a.clone(); thread::spawn(move || { dbg!(b); }); dbg!(a); The clone of the Arc lives in the same scope. Each thread gets its own clone with a different name. let a = Arc::new([1, 2, 3]); thread::spawn({ let a = a.clone(); move || { dbg!(a); } }); dbg!(a); The clone of the Arc lives in a different scope. We can use the same name in each thread. Because ownership is shared, reference counting pointers (Rc and Arc) have the same restrictions as shared references (&T). They do not give you mutable access to their contained value, since the value might be borrowed by other code at the same time. For example, if we were to try to sort the slice of integers in an Arc<[i32]>, the compiler would stop us from doing so, telling us that we’re not allowed to mutate the data: error[E0596]: cannot borrow data in an `Arc` as mutable | 6 | a.sort(); | ^^^^^^^^


Q- i like the concept of ownership here very mch 
Q- and how each thread can borrow data but do not owner it 
Q- but i think it look very abstract 

Q- why we need it in the first palace 
Q- explain it using a good “enginering analogy “ oky