nomicon icon indicating copy to clipboard operation
nomicon copied to clipboard

10.1.2. Base Code / Send and Sync. "Sync + Send"

Open kuzminrobin opened this issue 1 year ago • 3 comments

10.1.2. Base Code / Send and Sync. Fragment:

unsafe impl<T: Sync + Send> Send for Arc<T> {}
unsafe impl<T: Sync + Send> Sync for Arc<T> {}

It is unclear from the text of the book why the line about Send has the fragment Sync +:

unsafe impl<T: Sync + Send> Send for Arc<T> {}

and why the line about Sync has a fragment + Send:

unsafe impl<T: Sync + Send> Sync for Arc<T> {}

Would be nice to see in the book the clarification or details about that.


I also looked at (and it is still unclear)

kuzminrobin avatar Dec 13 '23 00:12 kuzminrobin

let v = Arc::new(Unsync);
let clone = v.clone();
thread::spawn(move || {
    clone.reference()
});
v.reference() // races with clone.reference()

Therefore Arc<Unsync> cannot be Send to prevent the cloned arc from being sent to another thread.

Similarly, Arc<Unsend> cannot be Sync to prevent getting cloned in another thread:

let v = Arc::new(Unsend);
worker.run(|| { // this closure only sends `&v` to the worker thread
    thread_local.set(v.clone());
});
drop(v);
worker.run(|| {
    let arc = thread_local.get();
    let unsend = arc.into_inner();
    drop(unsend); // we have somehow sent Unsend into the worker thread
});

The principle is that Arc can be used both by reference (by cloning) and by moving (by obviously sending the Arc), but its underlying reference can also be used as reference (normal Deref) and owned (by into_inner or otherwise becoming the owning reference after all other arcs are dropped).

SOF3 avatar Dec 13 '23 03:12 SOF3

@SOF3, thank you for your reply.

I assume that with Unsync and Unsend you mean values of types that are not Sync and not Send respectively.

I'm not sure what you mean with .reference() (I fail to find any docs about that) and intuitively I assume that you mean a pseudocode that deals with references to an Arc instance.

Having your reply I feel that I'm not mature enough in Rust to fully and clearly understand your explanation, such that I can explain the same to someone else. But the main point of this GitHub issue is not for me to understand, but to see the explanation in the book, the main words of this GitHub issue are: "Would be nice to see in the book the clarification or details about that".

Thanks.

kuzminrobin avatar Dec 14 '23 21:12 kuzminrobin

.reference() refers to any placeholder function with a &self receiver.

SOF3 avatar Dec 15 '23 07:12 SOF3