Sync only type makes no sense without Send in rust: You need to move objects across thread boundaries to make it sharable. Is this correct?

  • std::marker::Sync : a type is safe to use in a shared ownership model across threads
  • std::marker::Send : a type is safe to cross thread boundaries

A Sync only type makes no sense. You have to first move the object across thread boundaries to make it usable in a "true" shared context. You cannot share plain old references &T/&mut T across thread boundaries because the lifetimes (other than 'static) come into play.

  • What use cases will get covered by having a Sync only type ?
  • Sync trait seems to be of no value without a Send . Send is what enables sharing so why was Sync trait created ?

Please correct my assumptions if they are wrong.

Sorry for our spam filter holding your post. In the meantime I see you've posted the same thing in IRLO, too.

I think it may fit both forums, perhaps the engagement may be better here in URLO, but we'll see; I'm linking the other thread so people wanting to read existing answers or write new ones can be aware of what was already said elsewhere ^^


@steffahn Thank you!

This is simply not true. It's perfectly fine and possible to access a &T from two threads at the same time.

@H2CO3 But what about the lifetime considerations ? Do mean to say for scoped threads my argument is wrong ?

For example, yes. Also, Arc.

There are scoped threads so you can share a &T.

In std
In tokio

1 Like

agreed. I am new to rust and recently came to know about scoped threads. @H2CO3 Thank you.

What do you mean by Arc? Normally you send the Arc you don't share the &Arc

"scoped threads" you can share an &Arc saving needless atomic ref counts(.clone()) manipulations if you know the context of access is refined to a scope.

But why not just use &T instead of &Arc<T>.

you got a point there :thinking:

If you send an arc: Arc<T> across threads then &*arc is a &T, so you can now create a &T on multiple threads. So Arc<T>: Send needs T: Sync.


Recommending this post again:


Arc is a shared pointer but it's owning so it's 'static. It provides immutable by-ref access only to the pointed data. Therefore you can have many Arc<T>s to the same object in different threads, and dereference them to get &'short Ts in different threads (requiring T: Sync but not T: Send), where the Arc itself upholds the 'static bound required by thread::spawn(), so you don't even need scoped threads to observe why the distinction is important.

1 Like

Aahhhhh, lovely answer, thanks :slight_smile:

I'm going to say it again in a different way:
You use &Arc<T> and not &T because &'a Arc<T> can be cloned to obtain a new Arc<T> to the same value, which can be used even after the lifetime 'a is over.
When sending over a &'a T, it can only ever be used only for lifetime 'a.

1 Like