I have a general struct
with settings and an extra variable setting that I want to tune and play around with.
For all possible values in an integer range, I want to start a (scoped) thread with this variable set to that value. Depending on this value, they do slightly different work.
Each of these threads should be able to read the general settings struct.
use crossbeam; // 0.7.3
struct Settings {
// ... many fields
}
const MAX_FEASIBLE_SCORE: u8 = 10;
fn example(settings: Settings) {
crossbeam::scope(|scope| {
for score in 0..MAX_FEASIBLE_SCORE {
scope.spawn(|_| {
let work_result = do_cool_computation(&settings, score);
println!("{:?}", work_result);
});
}
})
.unwrap();
}
fn do_cool_computation(_: &Settings, _: u8) {}
This does not compile:
error[E0373]: closure may outlive the current function, but it borrows `score`, which is owned by the current function
--> src/lib.rs:12:25
|
10 | crossbeam::scope(|scope| {
| ----- has type `&crossbeam_utils::thread::Scope<'1>`
11 | for score in 0..MAX_FEASIBLE_SCORE {
12 | scope.spawn(|_| {
| ^^^ may outlive borrowed value `score`
13 | let work_result = do_cool_computation(&settings, score);
| ----- `score` is borrowed here
|
note: function requires argument type to outlive `'1`
--> src/lib.rs:12:13
|
12 | / scope.spawn(|_| {
13 | | let work_result = do_cool_computation(&settings, score);
14 | | println!("{:?}", work_result);
15 | | });
| |______________^
help: to force the closure to take ownership of `score` (and any other referenced variables), use the `move` keyword
|
12 | scope.spawn(move |_| {
| ^^^^^^^^
This would invalidate &settings
since the first loop iteration will take ownership of settings
in a move
closure.
The only easy ways to make it work were:
- copy the
Settings
struct into each thread (which in my real application is rather expensive) - introduce an
Arc
aroundsettings
, which also feels a bit unfortunate.
Is there a way that we can circumvent reference counting here? Is there a way we can move score
into the inner closure while still being allowed to reference settings
?