My scan()
function gets an input_slice
, then spans 4 worker-threads and sends the output to the channel tx
.
The merger()
thread collects the output from the channel tx
for printing.
From my understanding no thread can outlive the scan()
function. So the input_slice
can be given back securely after borrowing.
Why does the borrow checker wants mmap
to be static? What can I do?
extern crate memmap;
use std::sync::mpsc;
use std::sync::mpsc::SyncSender;
use std::fs::File;
use memmap::{Mmap, Protection};
use std::str;
extern crate scoped_threadpool;
use scoped_threadpool::Pool;
use std::thread;
const MESSAGE_BUF: usize = 20;
fn scan<'a> (mission: &Vec<&'a str>, input_slice: &'a [u8], pool: &mut Pool,
tx: &SyncSender<&'a str>) {
pool.scoped(|scope| {
for e in mission.iter().enumerate() {
let tx = tx.clone();
scope.execute(move || {
let m = std::str::from_utf8(input_slice).unwrap().clone();
//let m = e.1;
println!("{}",m);
tx.send(m).unwrap();
});
}
});
}
fn main() {
let f = File::open("./scanme.txt").unwrap();
let mmap = Mmap::open(&f, Protection::Read).unwrap();
let mission = vec!["T0", "T1", "T2", "T3"];
let n_threads = mission.len();
let (tx, rx) = mpsc::sync_channel(MESSAGE_BUF);
let merger = thread::spawn(move || {
for i in 0..n_threads*4 {
println!("\tListening...");
println!("\t\tGot: {:?}", rx.recv().expect("Err"));
}
});
let mut pool = Pool::new(n_threads as u32);
for i in 0..4 {
let input = unsafe {&mmap.as_slice()[i..10*i]}; //error: `mmap` does not live long enough
scan(&mission, &input, &mut pool, &tx);
}
merger.join().unwrap();
println!("All threads terminated.");
}
main.rs:62:30: 62:34 error: `mmap` does not live long enough
main.rs:62 let input = unsafe {&mmap.as_slice()[i..10*i]};
^~~~
main.rs:62:30: 62:34 note: reference must be valid for the static lifetime...
main.rs:44:58: 70:2 note: ...but borrowed value is only valid for the block suffix following statement 2 at 44:57
main.rs:44 let mmap = Mmap::open(&f, Protection::Read).unwrap();