Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
kuzminrobin opened this issue Dec 13, 2023 · 3 comments
Open

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

kuzminrobin opened this issue Dec 13, 2023 · 3 comments

Comments

@kuzminrobin
Copy link

kuzminrobin commented Dec 13, 2023

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 {}

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

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

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


I also looked at (and it is still unclear)

@SOF3
Copy link

SOF3 commented Dec 13, 2023

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).

@kuzminrobin
Copy link
Author

@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.

@SOF3
Copy link

SOF3 commented Dec 15, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants