The following code produces interesting results:
use std::thread;
fn main() {
let mut handles = Vec::new();
let mut v = vec![1, 2, 3, 4];
for x in v.chunks_exact_mut(2) {
let handle = thread::spawn(move || {
println!("Here's a vector: {:?}", x);
});
handles.push(handle);
}
for h in handles { h.join().unwrap(); }
}
error[E0597]: `v` does not live long enough
--> src/main.rs:7:14
|
7 | for x in v.chunks_exact_mut(2) {
| ^^^^^^^^^^^^^^^^^^^^^
| |
| borrowed value does not live long enough
| argument requires that `v` is borrowed for `'static`
...
16 | }
| - `v` dropped here while still borrowed
Why does 'chunking' v
change the lifetime? Without 'chunking' v
, the code performs correctly. So why now does it throw an error?
The problem here is that thread::spawn
completely decouples the lifetime from the rest, as the thread might continue to run while main
is already finished.
x
is a reference to a variable in main
, and there is no guarantee that main
lives longer than the thread.
I think what you really want here is a threading helper library like rayon
, as they already solve those problems internally:
use rayon::prelude::*;
fn main() {
let mut v = vec![1, 2, 3, 4];
v.par_chunks_exact_mut(2).for_each(|x: &mut [i32]| {
let thread_id = std::thread::current().id();
println!("{:?}: Here's a vector: {:?}", thread_id, x);
});
}
ThreadId(5): Here's a vector: [1, 2]
ThreadId(2): Here's a vector: [3, 4]
Without "chunking" v
, you're iterating over Vec<i32>
. This iterator produces items of type i32
, so, no references, no lifetimes, the requirements for thread::spawn()
(specifically the 'static
requirement) are met.
chunks_exact_mut()
, however, is defined on slices and gives iterator over &mut [T]
, so it does have a reference. And since this reference refers v
, which exists in main()
, it is not 'static
and does not work.
You can observe the same problem if you'll iterate over &v
instead of v
, since that iterator gives you &i32
s ( playground ):
error[E0597]: `v` does not live long enough
--> src/main.rs:7:14
|
7 | for x in &v {
| ^^
| |
| borrowed value does not live long enough
| argument requires that `v` is borrowed for `'static`
...
16 | }
| - `v` dropped here while still borrowed
Other than that, I'd recommend using rayon
as @Finomnis suggested.
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.