Is it possible to exchange data with streams without cloning?

When I delegate work to threads, I often have a piece of data that survives all threads, for example, numbers in the following example:

 use std::thread; fn main() { let numbers = vec![1, 2, 3]; let thread_a = thread::spawn(|| println!("{}", numbers.len())); let thread_b = thread::spawn(|| println!("{}", numbers.len())); thread_a.join().unwrap(); thread_b.join().unwrap(); } 

It did not change anywhere, and due to join it ensured that threads were made with it. However, Rust borrow the controller cannot say:

 error[E0373]: closure may outlive the current function, but it borrows 'numbers', which is owned by the current function --> src/main.rs:6:34 | 6 | let thread_a = thread::spawn(|| println!("{}", numbers.len())); | ^^ ------- 'numbers' is borrowed here | | | may outlive borrowed value 'numbers' | note: function requires argument type to outlive ''static' --> src/main.rs:6:20 | 6 | let thread_a = thread::spawn(|| println!("{}", numbers.len())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to force the closure to take ownership of 'numbers' (and any other referenced variables), use the 'move' keyword | 6 | let thread_a = thread::spawn(move || println!("{}", numbers.len())); | ^^^^^^^ 

All the solutions I've seen so far include cloning a piece of data (or cloning Arc data). Is it possible to do this without cloning?

+8
multithreading rust borrow-checker
source share
1 answer

Perhaps you are mistaken: Arc cloning is simply increasing the reference count and creating a copy of the pointer; he does not perform any additional distribution. Of course, the creation of Arc includes a distribution, but then you already allocate it to build Vec , so one additional fixed-size distribution is unlikely to hurt.

If all you really need is a length, you can simply compute it outside the closure of the stream and store it in a variable; usize does not have problems crossing the stream boundary.

The problem is that the compiler cannot infer from the use of join() that this thread has a limited lifetime ... it doesn't even try.

Prior to Rust 1.0, there was a thread::scoped that allowed non- 'static links to be passed, but it had to be destabilized due to memory security issues. See How can I pass a link to a stack variable to a stream? for alternatives.

+5
source share

All Articles