私は並行して処理したいRustのツリー構造を持っています。私の本当の問題はより複雑であるが、これは私が今持っている基本的にシリアルバージョンです:Rustの並行処理ツリー
は#[derive(Debug)]
enum BinaryTree {
Node(Box<BinaryTree>, Box<BinaryTree>),
Leaf(i32),
}
use BinaryTree::*;
impl BinaryTree {
/// Applies the given function to every leaf in the tree
fn map<F: Fn(i32) -> i32>(&mut self, f: &F) {
match *self {
Node(ref mut tree1, ref mut tree2) => {
tree1.map(f);
tree2.map(f);
}
Leaf(ref mut n) => *n = f(*n),
}
}
}
私が使用していないこれを並列化したいと思います:
- はロック
- スレッドプールを、またはそうでなければ、安全でないコード
問題は非常に自然トンを思わ再作成スレッド
extern crate scoped_pool;
impl BinaryTree {
/// Applies the given function to every leaf in the tree
fn map_parallel<F>(&mut self, f: &F, scope: &scoped_pool::Scope)
where F: Fn(i32) -> i32 + Send + Sync
{
match self {
&mut Node(ref mut tree1, ref mut tree2) => {
// Create new, smaller scope
scope.zoom(|scope2| {
// Concurrently process child nodes
scope2.recurse(|scope3| {
tree1.map_parallel(f, scope3);
});
scope2.recurse(|scope3| {
tree2.map_parallel(f, scope3);
});
}
);},
&mut Leaf(ref mut n) => *n = f(*n),
}
}
}
fn main() {
let mut tree = Node(
Box::new(Node(
Box::new(Node(
Box::new(Node(
Box::new(Node(
Box::new(Leaf(11)),
Box::new(Leaf(15)))),
Box::new(Leaf(13)))),
Box::new(Leaf(19)))),
Box::new(Leaf(5)))),
Box::new(Leaf(10)));
let thread_pool = scoped_pool::Pool::new(4);
tree.map_parallel(&|n| n + 1, &scoped_pool::Scope::forever(thread_pool));
println!("{:?}", tree);
}
しかし、これはデッドロックにはまり込むように見える、と私はその理由を理解していません。 Rustで並行して木を処理する慣用方法は何ですか?デッドロックで
VisualVMなどのプロファイリングツールを使用して、デッドロックしているスレッド(存在する場合)とそのオブジェクトを見つけるのに役立つことをお勧めします。 –