I am reading https://doc.rust-lang.org/book/ch20-02-multithreaded.html and it states the following:
...taking a job off the channel queue involves mutating the receiver, so the threads need a safe way to share and modify receiver; otherwise, we might get race conditions...
However when I look at the Receiver::recv docs it shows that the method takes an immutable reference, so why is the book implying that: Receiving from the Receiver mutates it and thus should be Mutex'd?
Would it not work correctly just behind an Arc (no mutex)?
Yes.
We know because in the Trait Implementation section of the documentation we see that it implements:
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> !Sync for Receiver<T> {}
This means it can not be shared safely without some form of synchronization structure such as a mutex.
That being said, you probably wont want to use a mutex. mpsc stands for Multiple Producer, Single Consumer. You likely want mpmc (Multiple Producer, Multiple Consumer) channels instead. The crossbeam-channel
provides this type of functionality and is the most popular crate (that I know of) for channels. You can create multiple receivers for a single channel by cloning the first receiver.