69、作用域线程(Scoped threads)
作用域线程
到目前为止,我们讨论过的所有生命周期问题都有一个共同的根源:生成的线程的生命周期可能超过其父线程。我们可以通过使用作用域线程来避免这个问题。
let v = vec![1, 2, 3];
let midpoint = v.len() / 2;
std::thread::scope(|scope| {
scope.spawn(|| {
let first = &v[..midpoint];
println!("Here's the first half of v: {first:?}");
});
scope.spawn(|| {
let second = &v[midpoint..];
println!("Here's the second half of v: {second:?}");
});
});
println!("Here's v: {v:?}");
让我们来看看发生了什么
作用域
std::thread::scope 函数创建一个新的作用域。std::thread::scope 将闭包作为输入,并带有一个参数:Scope 实例。
Scoped spawns
Scope 公开了一个 spawn 方法。与 std::thread::spawn 不同,使用 Scope 生成的所有线程都会在作用域结束时自动join。
如果我们把前面的例子 "翻译 "成 std::thread::spawn,就会像这样:
let v = vec![1, 2, 3];
let midpoint = v.len() / 2;
let handle1 = std::thread::spawn(|| {
let first = &v[..midpoint];
println!("Here's the first half of v: {first:?}");
});
let handle2 = std::thread::spawn(|| {
let second = &v[midpoint..];
println!("Here's the second half of v: {second:?}");
});
handle1.join().unwrap();
handle2.join().unwrap();
println!("Here's v: {v:?}");
借用环境中的变量
不过,前面翻译后的示例代码其实无法编译:编译器会报错,指出 &v 不能在我们生成的线程中使用,因为它的生命周期不是 'static。
但这在 std::thread::scope 中不是问题——我们可以安全地从环境中借用。
在我们的例子中,v 是在生成线程之前创建的,只有在 scope 返回之后才会被销毁。与此同时,所有在 scope 内部生成的线程都保证会在 scope 返回之前完成执行。因此,不存在悬空引用的风险。
编译器不会报错!
练习
// TODO: Given a vector of integers, split it in two halves
// and compute the sum of each half in a separate thread.
// Don't perform any heap allocation. Don't leak any memory.
// TODO: 给定一个整数向量,将其分成两半
// 并在一个单独的线程中计算每一半的和。
// 不要进行任何堆分配。不泄漏任何内存。
pub fn sum(v: Vec<i32>) -> i32 {
let v=v.leak();
let mid = v.len()/2;
let (v1,v2)=v.split_at(mid);
std::thread::scope(|scope|{
scope.spawn(||{
let mut sum=0;
for i in v1 {
sum += i;
}
sum
}).join().unwrap() + scope.spawn(||{
let mut sum=0;
for i in v2 {
sum+=i;
}
sum
}).join().unwrap()
})
}
官方答案:
pub fn sum(v: Vec<i32>) -> i32 {
let mid = v.len() / 2;
let (left, right) = v.split_at(mid);
std::thread::scope(|s| {
let left = s.spawn(|| left.iter().sum::<i32>());
let right = s.spawn(|| right.iter().sum::<i32>());
left.join().unwrap() + right.join().unwrap()
})
}
阅读剩余
版权声明:
作者:CN059
链接:https://www.cn059.com/2025/11/13/69%e3%80%81%e4%bd%9c%e7%94%a8%e5%9f%9f%e7%ba%bf%e7%a8%8b%ef%bc%88scoped-threads%ef%bc%89.html
文章版权归作者所有,未经允许请勿转载。
THE END
