为什么局部变量的生存时间不足以支持thread :: scoped? [英] Why doesn't a local variable live long enough for thread::scoped?
问题描述
鉴于示例2可以很好地编译,为什么示例1不能编译?这些示例之间的唯一区别在于,在示例1中,value
是函数局部变量,在示例2中,value
是函数的参数.
Why doesn't Example 1 compile given that Example 2 compiles just fine? The only difference between the examples is that in Example 1 value
is a function local variable, and in Example 2 value
is an argument to the function.
示例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:
These are the error messages I get trying to compile Example 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
是唯一的生存期.因此,作用域线程的生存期为value
的范围. value
在哪里合法? 在定义之后,直到超出范围为止,即在8:40的语句1之后的块后缀". join_guards
的生存期必须不超过此生存期,但是如果之前 value
定义了join_guards
,则情况并非如此.
join_guards
is a vector of scoped threads with a certain shared lifetime. That lifetime is determined by which variables it closes over: value
is the only one. Therefore, the lifetime of the scoped threads is the scope of value
. Where is value
legal? After it is defined and until it goes out of scope—that is, "the block suffix following statement 1 at 8:40". join_guards
must have as its lifetime a lifetime no greater than this, but if join_guards
is defined before value
, this is not the case.
解决方案是颠倒声明的顺序:
The solution is to reverse the order of declaration:
let value = AtomicUsize::new(0);
let mut join_guards = Vec::new();
这说明了第二个示例也可以工作的原因.
This explains why the second example works, also.
这篇关于为什么局部变量的生存时间不足以支持thread :: scoped?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!