我正在尝试实现BFS算法来检查图形是否是使用Rust的树。我是Rust的绝对初学者,当涉及到线程时,我对生命周期规范感到困惑。我的代码目前看起来像这样:
图形作为名为adj_mat
的邻接矩阵传递,它是矢量的矢量。访问的节点将在true
向量中标记为visited
。 parent
向量存储所访问的每个节点的父节点。函数is_tree_parallel
将调用bfs
函数,然后该函数将为当前线程的每个子函数生成一个新线程。当我使用adj_mat
,visited
和parent
向量作为全局变量时,此算法可以正常工作。
fn is_tree_parallel(adj_mat: &Vec<Vec<usize>>, nodes: usize) {
let mut visited = vec![false; nodes + 1];
let mut parent = vec![0; nodes + 1];
let mut node_current = 1;
bfs(&mut parent, &adj_mat, &mut visited, node_current, nodes);
// Do checking of visited array and CYCLE (shared memory variable used to
// detect cycle) and decide whether it is a tree
}
当我使用下面的函数来生成新线程时,这会给我一些错误:
cannot infer an appropriate lifetime due to conflicting requirements first, the lifetime cannot outlive the expression.
我知道这是由bfs
函数内的递归调用引起的。
fn bfs(mut parent: &mut Vec<usize>, adj_mat: &Vec<Vec<usize>>, mut visited: &mut Vec<bool>, mut currentnode: usize, nodes: usize) {
visited[currentnode as usize] = true;
for i in 0..nodes {
if adj_mat[currentnode - 1][i as usize] == 1 && (i + 1) != parent[currentnode] {
if visited[i + 1 ] {
CYCLE = true;
return;
} else {
if RUNTHREADS < NTHREADS { //RUNTHREADS and NTHREADS will limit the number of threads spawned
RUNTHREADS += 1;
let mut visited = Arc::new(Mutex::new(visited));
let mut parent = Arc::new(Mutex::new(parent));
let adj_mat = Arc::new(adj_mat);
let visited = visited.clone();
let parent = parent.clone();
let adj_mat = adj_mat.clone();
thread::spawn(move || {
let visited = visited.lock().unwrap();
let parent = parent.lock().unwrap();
bfs(&mut parent, &adj_mat, &mut visited, i, nodes);
}).join();
} else {
bfs(parent, adj_mat, visited, i, nodes);
}
}
}
}
}
我收到的错误:
src/main.rs:134:69: 134:76 error: cannot infer an appropriate lifetime due to conflicting requirements [E0495]
src/main.rs:134 let mut visited = Arc::new(Mutex::new(visited));
src/main.rs:134:49: 134:57 note: first, the lifetime cannot outlive the expression at 134:48...
src/main.rs:134 let mut visited = Arc::new(Mutex::new(visited));
src/main.rs:134:49: 134:57 note: ...so that a type/lifetime parameter is in scope here
src/main.rs:134 let mut visited = Arc::new(Mutex::new(visited));
src/main.rs:134:49: 134:78 note: but, the lifetime must be valid for the call at 134:48...
src/main.rs:134 let mut visited = Arc::new(Mutex::new(visited));
src/main.rs:134:58: 134:77 note: ...so that argument is valid for the call
src/main.rs:134 let mut visited = Arc::new(Mutex::new(visited));
我做得对吗?我怎样才能纠正它们?有没有其他方法来使用线程实现这些递归调用?