2

Here is the code that wont compile.

use std::{
    sync::{
        mpsc::{self, Receiver, Sender},
        Arc,
    },
    thread,
};

struct S1 {
    rx: Receiver<i32>,
}

pub struct S2 {
    inner: Arc<S1>,
    tx: Sender<i32>,
}

impl S2 {
    pub fn new() -> S2 {
        let (tx, rx): (Sender<i32>, Receiver<i32>) = mpsc::channel();
        let st1 = S1 { rx };
        let st2 = S2 {
            tx,
            inner: Arc::new(st1),
        };
        st2
    }

    pub fn start(&mut self) {
        let inner = &self.inner.clone();
        let _jh = thread::spawn(move || loop {
            inner.rx.recv().unwrap();
        });
    }
}

fn main() {}

S2 is the client-visible code and S1 is the internal state maintained by the backend thread. This seems to be a common Rust idiom.

Here is the error:

error[E0277]: `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
   --> src/main.rs:31:19
    |
31  |         let _jh = thread::spawn(move || loop {
    |                   ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
    |
    = help: within `S1`, the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<i32>`
    = note: required because it appears within the type `S1`
    = note: required because of the requirements on the impl of `std::marker::Sync` for `std::sync::Arc<S1>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::Arc<S1>`
    = note: required because it appears within the type `[closure@src/main.rs:31:33: 33:10 inner:&std::sync::Arc<S1>]`

This is not a duplicate of Why do I get an error that "Sync is not satisfied" when moving self, which contains an Arc, into a new thread?. I don't care if I have the Arc or not. I just want my constructor of the client visible thing (S2) to create a channel and have the send on the client side and the receiver in the background thread. I can find no way of doing that.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
pm100
  • 48,078
  • 23
  • 82
  • 145
  • 4
    You should make lambda [take ownership of the captured value](https://doc.rust-lang.org/stable/rust-by-example/fn/closures/capture.html): add `move ` before `||` – yeputons Jul 25 '20 at 23:40
  • The second example has a thread receiving https://doc.rust-lang.org/std/thread/fn.spawn.html#examples – Will Jul 25 '20 at 23:41
  • *I don't care if I have the `Arc` or not* — then [remove the `Arc`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=9d3754a9d5fd2270941c172b4f323b3f). Note that MPSC means **m**ultiple **p**roducer **s**ingle **c**onsumer. You are attempting to create multiple consumers by cloning the `Receiver`. As stated in the duplicate, if you want that, pick a different channel library. – Shepmaster Aug 04 '20 at 14:03
  • @Shepmaster if I remove arc. I get the same error – pm100 Aug 04 '20 at 15:45
  • I [linked to a solution without the `Arc`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=9d3754a9d5fd2270941c172b4f323b3f) — what is the problem with it? – Shepmaster Aug 04 '20 at 15:52
  • aha - you snuck an Option in there. Why an option, I mean its not optional, there is a receiver, there is never not a receiver. I know there has to be a logical reason for it, but it feels like this stuff is a bunch of magic spells, you have to keep trying till one works :-(. I know sometime in the future this will be second nature to me, but not at the moment – pm100 Aug 04 '20 at 17:42
  • i just had another question answered with the same - use an option answer. I get what it means now. SInce these are non copyable objects (there can only be one) If I want to transport one from point a to point b via a slot somewhere (a field in a struct) when I hand it over to point B it has to not be in the transporting slot any more. (and not at point a either). To me thats what I thought an Arc was for. THere really is only one thing and I just pass a pointer to it around, but apparently not. Need to think on that a bit more – pm100 Aug 04 '20 at 17:50

0 Answers0