multithreading - Copying in Vectors to a Thread -
considering following code, wish have access both client
, requests
within thread, not:
for _x in 0..100 { let handle = thread::spawn(move || { let start = time::precise_time_s(); let res = client.get("http://jacob.uk.com") .header(connection::close()) .send().unwrap(); let end = time::precise_time_s(); requests.push(request::new(end-start)); }); handle.join().unwrap() }
i following compiler error:
compiling herd v0.1.0 (file:///users/jacobclark/desktop/learningrust/herd) src/main.rs:41:23: 41:29 error: capture of moved value: `client` src/main.rs:41 let res = client.get("http://jacob.uk.com") ^~~~~~ src/main.rs:38:41: 48:10 note: `client` moved closure environment here because has type `[closure(())]`, non-copyable src/main.rs:38 let handle = thread::spawn(move || { src/main.rs:39 let start = time::precise_time_s(); src/main.rs:40 src/main.rs:41 let res = client.get("http://jacob.uk.com") src/main.rs:42 .header(connection::close()) src/main.rs:43 .send().unwrap(); ... src/main.rs:38:41: 48:10 help: perhaps meant use `clone()`? src/main.rs:47:13: 47:21 error: capture of moved value: `requests` src/main.rs:47 requests.push(request::new(end-start)); ^~~~~~~~ src/main.rs:38:41: 48:10 note: `requests` moved closure environment here because has type `[closure(())]`, non-copyable src/main.rs:38 let handle = thread::spawn(move || { src/main.rs:39 let start = time::precise_time_s(); src/main.rs:40 src/main.rs:41 let res = client.get("http://jacob.uk.com") src/main.rs:42 .header(connection::close()) src/main.rs:43 .send().unwrap(); ... src/main.rs:38:41: 48:10 help: perhaps meant use `clone()`? src/main.rs:53:24: 53:32 error: use of moved value: `requests` src/main.rs:53 request::mean_time(requests); ^~~~~~~~ src/main.rs:38:41: 48:10 note: `requests` moved closure environment here because has type `[closure(())]`, non-copyable src/main.rs:38 let handle = thread::spawn(move || { src/main.rs:39 let start = time::precise_time_s(); src/main.rs:40 src/main.rs:41 let res = client.get("http://jacob.uk.com") src/main.rs:42 .header(connection::close()) src/main.rs:43 .send().unwrap(); ... src/main.rs:38:41: 48:10 help: perhaps meant use `clone()`? error: aborting due 3 previous errors not compile `herd`
.
firstly, minimal examples useful:
use std::thread; fn main() { let mut items = vec::new(); _ in 0..100 { thread::spawn(move || { items.push(()); }); } }
so what's problem here? well, you're moving items
closure 100 times - can move once!
to share data across multiple threads, need
to remove data races - put in
mutex
(or don't mutate it).to keep alive - put in
arc
(atomically reference-counted pointer).
use std::sync::{arc, mutex}; use std::thread; fn main() { let items = arc::new(mutex::new(vec::new())); _ in 0..10 { let thread_items = items.clone(); let handle = thread::spawn(move || { thread_items.lock().unwrap().push(()); }); handle.join().unwrap(); } println!("{:?}", items); }
Comments
Post a Comment