Why Arc<Mutex<SomeType>> still implies SomeType must be Sync + Send?

In Rust, if I have a type that is not safe to send between threads, I wrap it with Arc<Mutex<T>>. This way I'm guaranteed that when I access it, I need to unlock it first. However, Rust still complains when SomeType does not implement Send + Sync.

Shoudln't it work for any type? In my case, SomeType is a struct that accesses a C object through FFI, so I cannot mark it as Sync + Send.

What can I do in this case and why Rust wont accept Arc<Mutex<SomeType>> as safe to share between threads?

Isn't it requires just Send? The Mutex<T> is to share T: !Sync types between threads, but Send is still needed since you can use mutex as a channel to transfer values between threads. std::mem::swap() to put a value in a thread, and swap it out in another thread, and it's moved.


Here is what the std docs say

Arc<T> will implement Send and Sync as long as the T implements Send and Sync . Why can't you put a non-thread-safe type T in an Arc<T> to make it thread-safe? This may be a bit counter-intuitive at first: after all, isn't the point of Arc<T> thread safety? The key is this: Arc<T> makes it thread safe to have multiple ownership of the same data, but it doesn't add thread safety to its data. Consider Arc< RefCell<T> > . RefCell<T> isn't Sync , and if Arc<T> was always Send , Arc< RefCell<T> > would be as well. But then we'd have a problem: RefCell<T> is not thread safe; it keeps track of the borrowing count using non-atomic operations.

1 Like

Generally if a type may not be sent across threads at all, then it doesn't matter if you put it behind a mutex. You still may not move it across threads.

A mutex lets you guarantee that no two threads access it at the same time, which means you don't need Sync. But you must still have Send on the inner type.


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.