I'm aware that the Sender of std::sync::mpsc::channel() should not be used be two threads in parallel, but be cloned so each thread has its own copy.
However, how is the implementation of "clone" under the hood. Could I (with the help of some unsafe code) call clone from two threads concurrently without race conditions?
I'm asking this because I have a rocket app and want the handler threads to get a common state injected, the sender, and clone this one to then use it thread safe.
I'm aware of other, more proper solutions, but I'm interested if that would, in theory, be possible.
It's implementation details, so you can't rely on it.Even if it was callable from two threads concurrently without race conditions, Sender being !Sync means that it could be changed at any time in a way that would introduce such race conditions.
That does not change the situation re: cloning in multiple threads:
use std::thread;
use std::sync::mpsc::channel;
fn main() {
let (sender1, receiver) = channel();
let sender2 = sender1.clone();
let t1 = thread::spawn(move || {
sender1.send(1).unwrap();
let sender = sender1.clone();
sender.send(10).unwrap();
});
let t2 = thread::spawn(move || {
sender2.send(2).unwrap();
let sender = sender2.clone();
sender.send(20).unwrap();
});
println!("{}", receiver.recv().unwrap());
println!("{}", receiver.recv().unwrap());
println!("{}", receiver.recv().unwrap());
println!("{}", receiver.recv().unwrap());
let res = t1.join();
let res = t2.join();
}
Ok, to be more precise, concurrently calling clone on two different clones of the sender is fine. Concurrently calling clone on the same sender twice is not.
The std Sender is not Sync, so it's not safe to simultaneously access it from multiple threads, under any circumstances.
You should always use crossbeam-channel instead of std::mpsc. It's always significantly faster. It's more flexible (including Sender being Sync and safe to clone from any thread), and has more polished API.