My program creates a grid of numbers, then based on the sum of the numbers surrounding each on the grid the number will change in a set way. I'm using two vectors currently, filling the first with random numbers, calculating the changes, then putting the new values in the second vector. After the new values go into the second vector I then push them back into the first vector before going through the next loop. The error I get currently is:
error[E0499]: cannot borrow `grid_a` as mutable more than once at a time
--> src\main.rs:40:29
|
38 | thread::scope(|s| {
| - has type `&crossbeam::thread::Scope<'1>`
39 | for j in 0..grid_b.len() {
40 | s.spawn(|_| {
| - ^^^ `grid_a` was mutably borrowed here in the previous iteration of the loop
| _____________________|
| |
41 | | grid_a[j] = grid_b[j];
| | ------ borrows occur due to use of `grid_a` in closure
42 | | });
| |______________________- argument requires that `grid_a` is borrowed for `'1`
My current code is below. I'm way more familiar with C++ and C#, in the process of trying to learn Rust for this assignment. If I remove the thread everything compiles and runs properly. I'm not understanding how to avoid the multiple borrow. Ideally I'd like to use a separate thread::scope on with the for loop above the existing thread::scope as well.
use crossbeam::thread;
use rand::Rng;
use std::sync::{Arc, Mutex};
use std::thread::sleep;
use std::time::Duration;
use std::time::Instant;
static NUMROWS: i32 = 4;
static NUMCOLUMNS: i32 = 7;
static GRIDSIZE: i32 = NUMROWS * NUMCOLUMNS;
static PLUSNC: i32 = NUMCOLUMNS + 1;
static MINUSNC: i32 = NUMCOLUMNS - 1;
static NUMLOOP: i32 = 7;
static HIGH: u32 = 35;
fn main() {
let start = Instant::now();
let length = usize::try_from(GRIDSIZE).unwrap();
let total_checks = Arc::new(Mutex::new(0));
let mut grid_a = Vec::<u32>::with_capacity(length);
let mut grid_b = Vec::<u32>::with_capacity(length);
grid_a = fill_grid();
for h in 1..=NUMLOOP {
println!("-- {} --", h);
print_grid(&grid_a);
if h != NUMLOOP {
for i in 0..grid_a.len() {
let mut total_checks = total_checks.lock().unwrap();
grid_b[i] = checker(&grid_a, i.try_into().unwrap());
*total_checks += 1;
}
grid_a.clear();
thread::scope(|s| {
for j in 0..grid_b.len() {
s.spawn(|_| {
grid_a[j] = grid_b[j];
});
}
})
.unwrap();
grid_b.clear();
}
}
When you access a vector (or any slice) via index you're borrowing the whole vector. You can use iterators which can give you mutable references to all the items in parallel.