简体   繁体   中英

Copying in Vectors to a Thread

Considering the following code, I wish to have access to both client and requests within my thread, currently I do 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 get the 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 into closure environment here because it has type `[closure(())]`, which is 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 you meant to 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 into closure environment here because it has type `[closure(())]`, which is 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 you meant to 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 into closure environment here because it has type `[closure(())]`, which is 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 you meant to use `clone()`?
error: aborting due to 3 previous errors
Could not compile `Herd`

.

Firstly, minimal examples are really useful:

use std::thread;

fn main() {
    let mut items = Vec::new();

    for _ in 0..100 {
        thread::spawn(move || {
            items.push(());
        });
    }
}

So what's the problem here? Well, you're moving items into a closure 100 times - but you can only move it once!

To share data across multiple threads, you need

  • To remove data races - put it in a Mutex (or don't mutate it).

  • To keep it alive - put it in an Arc ( A tomically R eference- C ounted pointer).

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let items = Arc::new(Mutex::new(Vec::new()));

    for _ in 0..10 {
        let thread_items = items.clone();

        let handle = thread::spawn(move || {
            thread_items.lock().unwrap().push(());
        });

        handle.join().unwrap();
    }

    println!("{:?}", items);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM