为什么局部变量的寿命不够 thread::scoped?
Why doesn't a local variable live long enough for thread::scoped?
既然示例 2 可以正常编译,为什么示例 1 不能编译?示例之间的唯一区别是示例 1 中 value
是函数局部变量,而示例 2 中 value
是函数的参数。
示例 1
#![feature(scoped)]
use std::thread;
use std::sync::atomic::{AtomicUsize, Ordering};
pub fn foo<F>() {
let mut join_guards = Vec::new();
let value = AtomicUsize::new(0);
for _ in 0..10 {
join_guards.push(thread::scoped(|| {
value.fetch_add(1, Ordering::SeqCst);
}));
}
}
示例 2
#![feature(scoped)]
use std::thread;
use std::sync::atomic::{AtomicUsize, Ordering};
pub fn foo<F>(value: AtomicUsize) {
let mut join_guards = Vec::new();
for _ in 0..10 {
join_guards.push(thread::scoped(|| {
value.fetch_add(1, Ordering::SeqCst);
}));
}
}
这些是我在尝试编译示例 1 时收到的错误消息:
error: `value` does not live long enough
join_guards.push(thread::scoped(|| {
value.fetch_add(1, Ordering::SeqCst);
}));
note: reference must be valid for the block at 6:20...
pub fn foo<F>() {
let mut join_guards = Vec::new();
let value = AtomicUsize::new(0);
for _ in 0..10 {
join_guards.push(thread::scoped(|| {
note: ...but borrowed value is only valid for the block suffix following statement 1 at 8:40
let value = AtomicUsize::new(0);
for _ in 0..10 {
join_guards.push(thread::scoped(|| {
value.fetch_add(1, Ordering::SeqCst);
}));
join_guards
是具有特定共享生命周期的作用域线程向量。该生命周期由它关闭的变量决定:value
是唯一的一个。因此,scoped线程的生命周期是value
的范围。 value
哪里合法? 在它被定义之后,直到它超出范围——也就是说,“8:40 处语句 1 之后的块后缀”。 join_guards
的生命周期必须不超过这个,但是如果join_guards
定义在之前 value
,则不是这样。
解决办法是把声明的顺序倒过来:
let value = AtomicUsize::new(0);
let mut join_guards = Vec::new();
这也解释了为什么第二个示例也有效。
既然示例 2 可以正常编译,为什么示例 1 不能编译?示例之间的唯一区别是示例 1 中 value
是函数局部变量,而示例 2 中 value
是函数的参数。
示例 1
#![feature(scoped)]
use std::thread;
use std::sync::atomic::{AtomicUsize, Ordering};
pub fn foo<F>() {
let mut join_guards = Vec::new();
let value = AtomicUsize::new(0);
for _ in 0..10 {
join_guards.push(thread::scoped(|| {
value.fetch_add(1, Ordering::SeqCst);
}));
}
}
示例 2
#![feature(scoped)]
use std::thread;
use std::sync::atomic::{AtomicUsize, Ordering};
pub fn foo<F>(value: AtomicUsize) {
let mut join_guards = Vec::new();
for _ in 0..10 {
join_guards.push(thread::scoped(|| {
value.fetch_add(1, Ordering::SeqCst);
}));
}
}
这些是我在尝试编译示例 1 时收到的错误消息:
error: `value` does not live long enough
join_guards.push(thread::scoped(|| {
value.fetch_add(1, Ordering::SeqCst);
}));
note: reference must be valid for the block at 6:20...
pub fn foo<F>() {
let mut join_guards = Vec::new();
let value = AtomicUsize::new(0);
for _ in 0..10 {
join_guards.push(thread::scoped(|| {
note: ...but borrowed value is only valid for the block suffix following statement 1 at 8:40
let value = AtomicUsize::new(0);
for _ in 0..10 {
join_guards.push(thread::scoped(|| {
value.fetch_add(1, Ordering::SeqCst);
}));
join_guards
是具有特定共享生命周期的作用域线程向量。该生命周期由它关闭的变量决定:value
是唯一的一个。因此,scoped线程的生命周期是value
的范围。 value
哪里合法? 在它被定义之后,直到它超出范围——也就是说,“8:40 处语句 1 之后的块后缀”。 join_guards
的生命周期必须不超过这个,但是如果join_guards
定义在之前 value
,则不是这样。
解决办法是把声明的顺序倒过来:
let value = AtomicUsize::new(0);
let mut join_guards = Vec::new();
这也解释了为什么第二个示例也有效。