I have a struct which roughly looks as follows
struct Node {
id: Arc<i32>,
data: Arc<Mutex<i32>>, // Actually not i32, but that is not important for this question.
rx: Receiver<()>,
tx: Sender<()>
}
I use Receiver
and Sender
from mpsc::channel
.
I want to share this across multiple threads. I have one "user" thread in which the user of Node
executes some functions on Node
. This will cause some UDP messages being sent to other computers and this thread will block on rx.recv()
. In the background I have one or more threads that perform a blocking receive call on UDP sockets. When they receive a message they update the data
field of the Node
struct and when a background thread notices that sufficiently many messages have been received, it will send ()
using tx.send()
, to let the user-thread continue its execution.
To share a Node
instance to another thread, I do something like this:
let node: Arc<Node> = ...
let node_for_background_thread = Arc::clone(&node);
let background_thread_handle = thread::spawn(move || {
node_for_background_thread.start_receive_loop();
});
I need to access all fields of Node
(e.g. id
and data
) in both the user thread and the background threads. That's why I want to share a single instance of Node
across them. But neither Receiver
nor Sender
is Sync
, so the above doesn't compile. I know I can clone Sender
to put an owned one of them in each background thread.
One solution I see is to not include rx
and tx
in Node
. But then I would lose encapsulation since then the creator of Node
instances would have to create the channel and also spawn the background threads. I want to keep it all encapsulated in Node
if possible.
The code snipper above is where I could manually clone the Sender
. I don't need to clone the Receiver
since I will only ever have one thread that will use it.