英文:
Summing successes inside of a Rayon Parallelized for loop in Rust
问题
在编译时出现了"Cannot assign to won_games
, as it is a captured variable in a Fn
closure"错误。
英文:
I was having trouble understanding the monty hall problem so I put together some Rust. I have a function which determines whether or not a participant wins a game show. If they win the game show then the function returns true, otherwise it returns false. I wanted to test for very large numbers so I added a Rayon Parallel Iterator to the for loop. The code follows:
fn gameshow(num_doors: usize, num_runs: usize, change: bool) -> usize {
let mut won_games:usize = 0;
let runs: Vec<Vec<bool>> = vec![stagehand(num_doors); num_runs]; // Creates common solution
if change {
ParallelIterator::for_each(IntoParallelIterator::into_par_iter(runs), |game| {
let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
if winner { won_games += 1;}
});
}
else {
ParallelIterator::for_each(IntoParallelIterator::into_par_iter(runs), |game| {
let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
if winner { won_games += 1;}
});
}
won_games
}
When compiling it throws a "Cannot assign to won_games
, as it is a captured variable in a Fn
closure" error.
答案1
得分: 3
你不能在并行中修改捕获的外部状态,否则可能会发生数据竞争。Rayon专门设计用于防止这种情况。
不要使用for_each
,而是使用map
将每个bool
映射为0或1,然后取其sum
:
fn gameshow(num_doors: usize, num_runs: usize, change: bool) -> usize {
let runs: Vec<Vec<bool>> = vec![stagehand(num_doors); num_runs]; // 创建公共解决方案
let won_games = if change {
runs.into_par_iter().map(|game| {
let winner: bool = run_game_no_change(game); // 在测试时每个门都是随机选择的
if winner { 1 } else { 0 }
}).sum()
} else {
runs.into_par_iter().map(|game| {
let winner: bool = run_game_no_change(game); // 在测试时每个门都是随机选择的
if winner { 1 } else { 0 }
}).sum()
};
won_games
}
英文:
You can't modify a captured external state in parallel, or you could have data races. Rayon is specifically designed to prevent this.
Instead of for_each
, use map
to map each bool
to 0 or 1, then take the sum
of that:
fn gameshow(num_doors: usize, num_runs: usize, change: bool) -> usize {
let runs: Vec<Vec<bool>> = vec![stagehand(num_doors); num_runs]; // Creates common solution
let won_games = if change {
runs.into_par_iter().map(|game| {
let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
if winner { 1 } else { 0 }
}).sum()
} else {
runs.into_par_iter().map(|game| {
let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
if winner { 1 } else { 0 }
}).sum()
};
won_games
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论