What happens when an Arc is cloned?

后端 未结 3 866
耶瑟儿~
耶瑟儿~ 2020-12-05 23:58

I am learning concurrency and want to clarify my understanding on the following code example from the Rust book. Please correct me if I am wrong.

use std::         


        
相关标签:
3条回答
  • 2020-12-06 00:05

    [...] what is happening on let data = data.clone()?

    Arc stands for Atomically Reference Counted. An Arc manages one object (of type T) and serves as a proxy to allow for shared ownership, meaning: one object is owned by multiple names. Wow, that sounds abstract, let's break it down!

    Shared Ownership

    Let's say you have an object of type Turtle

    0 讨论(0)
  • 2020-12-06 00:08

    I am not an expert on the standard library internals and I am still learning Rust.. but here is what I can see: (you could check the source yourself too if you wanted).

    Firstly, an important thing to remember in Rust is that it is actually possible to step outside the "safe bounds" that the compiler provides, if you know what you're doing. So attempting to reason about how some of the standard library types work internally, with the ownership system as your base of understanding may not make lots of sense.

    Arc is one of the standard library types that sidesteps the ownership system internally. It essentially manages a pointer all by itself and calling clone() returns a new Arc that points at the exact same piece of memory the original did.. with an incremented reference count.

    So on a high level, yes, clone() returns a new Arc instance and the ownership of that new instance is moved into the left hand side of the assignment. However, internally the new Arc instance still points where the old one did.. via a raw pointer (or as it appears in the source, via a Shared instance, which is a wrapper around a raw pointer). The wrapper around the raw pointer is what I imagine the documentation refers to as an "owned handle".

    0 讨论(0)
  • 2020-12-06 00:12

    std::sync::Arc is a smart pointer, one that adds the following abilities:

    An atomically reference counted wrapper for shared state.

    Arc (and its non-thread-safe friend std::rc::Rc) allow shared ownership. That means that multiple "handles" point to the same value. Whenever a handle is cloned, a reference counter is incremented. Whenever a handle is dropped, the counter is decremented. When the counter goes to zero, the value that the handles were pointing to is freed.

    Note that this smart pointer does not call the underlying clone method of the data; in fact, there may doesn't need to be an underlying clone method! Arc handles what happens when clone is called.

    What is the new "owned handle"? It sounds like a reference to the data?

    It both is and isn't a reference. In the broader programming and English sense of the word "reference", it is a reference. In the specific sense of a Rust reference (&Foo), it is not a reference. Confusing, right?


    The second part of your question is about std::sync::Mutex, which is described as:

    A mutual exclusion primitive useful for protecting shared data

    Mutexes are common tools in multithreaded programs, and are well-described elsewhere so I won't bother repeating that here. The important thing to note is that a Rust Mutex only gives you the ability to modify shared state. It is up to the Arc to allow multiple owners to have access to the Mutex to even attempt to modify the state.

    This is a bit more granular than other languages, but allows for these pieces to be reused in novel ways.

    0 讨论(0)
提交回复
热议问题