0

I'm creating a network distributor. I have a member variable that is a potentially very large vector. I need a separate thread to handle when I need to write the vector to disk as I can not risk it blocking the network.

I want to send the vector to the writer_thread (probably moving it is required so it doesn't take time) and then let the main thread start working with a new vector while the writer_thread does its job without interrupting the main program.

use std::sync::mpsc::{self, channel};
use std::thread;

struct NetDist {
    sender: mpsc::Sender<Vec<Object>>,
    large_vec: Vec<Object>,
}

impl NetDist {
    fn new() -> Netdist {
        let (sender, receiver) = channel::<Vec<Message>>();
        NetDist {
            sender,
            large_vec: Vec::new(),
        };

        thread::spawn(move || NetDist::writer_thread(receiver));
    }

    fn main_thread(&mut self) {
        loop {
            // Do stuff and fill up large_vec

            // Here I want to move the memory of large_vec to the writer_thread
            // and allocate new memory for large_vec that will be sent later.
            // ERROR: Cannot move out of borrowed content
            self.sender.send(self.large_vec);

            // Allocate new memory and let writer_thread handle the sent memory
            self.large_vec = Vec::new();
        }
    }

    fn writer_thread(receiver: mpsc::Receiver<Vec<Object>>) {
        loop {
            let mut largevec = receiver.recv().unwrap();

            // Write to disk....

            // Free memory when writing is done
            largevec.clear();
        }
    }
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jackbob
  • 61
  • 1
  • 6
  • 2
    I believe your question is answered by the answers of [How can I swap in a new value for a field in a mutable reference to a structure?](https://stackoverflow.com/q/27098694/155423). If you disagree, please [edit] your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Jun 20 '18 at 14:14
  • 3
    TL; DR the duplicate: `let v = mem::replace(&mut self.large_vec, Vec::new()); self.sender.send(v);` – Shepmaster Jun 20 '18 at 14:14
  • Does `large_vec` need to be an attribute of `NetDist`? The example looks like it could well work as a local variable in `main_thread`'s loop ([playground](https://play.rust-lang.org/)). – MB-F Jun 20 '18 at 14:16
  • Yes I believe you are totally right Shepmaster! I can't try for myself until tomorrow but I'm fairly certain that your example is exactly what I need – Jackbob Jun 20 '18 at 14:27
  • kazemakase, this is unfortunately an extremely simplified example of the real deal so as of now it is not possible at all to keep the variable local to the scope of main_thread as that function doesn't really exist – Jackbob Jun 20 '18 at 14:31

0 Answers0