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 T
does not implement Send + Sync
.
Shouldn't it work for any type? In my case, T
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 won't Rust accept Arc<Mutex<T>>
as safe to share between threads?
Just because you are the only one accessing something (at a time) does not mean it suddenly become okay to access things from different threads. It merely prevents one issue: data races. But there may be other issues with moving objects across threads.
For example it's common for low-level windowing APIs to only be able to be called from the main thread. Many low-level APIs are also only callable from the thread they were initialized in. If you wrap these APIs in Rust objects, you don't want these objects moving across threads no matter what.
The technical reason is the Mutex
implements Sync
only if T
is Send
.
And what helped me to see why T
has to be Send
is to think of thread local storage: Imagine the type involves some thread local variable, say a simple counter. Accessing it from different threads can result in reading different values, because each thread has its own instance. Therefore this type cannot be Send
. And a Mutex
must not make it Sync
, because even with synchronized/exclusive access, seeing different values wouldn't be sound.
Going further, the property of being "pinned to a thread" can be transitive. Perhaps the type itself doesn't involve any thread local storage itself, but relies on some external low level APIs that does etc. I'd assume that as soon as there is some dependency on something this is specific to one particular thread, there is no amount of wrapping that can allow accessing it from different threads safely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With