the defination is
impl Sync for Arc<T> where T: Sync + Send;
e.g, T: Sync is not enough.
Any example to show a T: Sync, and Arc<T>: !Sync
?
the defination is
impl Sync for Arc<T> where T: Sync + Send;
e.g, T: Sync is not enough.
Any example to show a T: Sync, and Arc<T>: !Sync
?
You can get back the ownership from a unique Arc using try_unwrap()
. But the current unique owner might not have been created on the same thread where the original value lived, if the Arc
was cloned and the original one was dropped in the meantime.
Since sending a reference-to-Arc
to another thread allows you to clone()
it inside that thread, &Arc<T>: Send
and thus Arc<T>: Sync
must be tied to T: Send
.
std::sync::MutexGuard<'_, i32>
is Sync
but not Send
, so Arc<MutexGuard<'_, i32>>
is not Sync
. If it were Sync
, you could lock a Mutex<i32>
on thread A, put the MutexGuard
into an Arc
, and send a reference to that Arc
to thread B. After that, you could clone the Arc
from thread B and drop the original Arc
on thread A. At that point, thread B could take ownership of the MutexGuard
using try_unwrap
as @H2CO3 described, and then the guard would be dropped on a different thread from where it was created—which is unsound.
Actually, I don't think try_unwrap
is even necessary: as long as thread B gets a unique Arc
and no further cloning occurs, the contained value will be dropped on B when the Arc
is dropped, right?
Yep, the very Drop
impl which may drop the T
on another thread if the last Arc
owner ends up here already causes the T : Send
requirement. More generally, for any wrapper featuring shared ownership, the Send
and Sync
notions become entangled.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.