如何将对堆栈变量的引用传递给线程?我正在编写一个WebSocket服务器,其中一个Web客户端连接到一个多线程计算机AI上下棋。WebSocket服务器希望传递一个Logger对象进入人工智能代码。这个Logger对象将把日志行从AI排到Web客户端。这个Logger必须包含对客户端连接的引用。我对生命如何与线程交互感到困惑。我用一个Wrapper由类型参数化的结构。这个run_thread函数尝试展开该值并将其记录下来。use std::fmt::Debug;use std::thread;struct Wrapper<T: Debug> {
val: T,}fn run_thread<T: Debug>(wrapper: Wrapper<T>) {
let thr = thread::spawn(move || {
println!("{:?}", wrapper.val);
});
thr.join();}fn main() {
run_thread(Wrapper::<i32> { val: -1 });}这个wrapper参数存在于堆栈中,且其生存期不会延长。run_thread的堆栈框架,即使在堆栈帧结束之前线程将被连接。我可以从堆栈中复制值:use std::fmt::Debug;use std::thread;struct Wrapper<T: Debug + Send> {
val: T,}fn run_thread<T: Debug + Send + 'static>(wrapper: Wrapper<T>) {
let thr = thread::spawn(move || {
println!("{:?}", wrapper.val);
});
thr.join();}fn main() {
run_thread(Wrapper::<i32> { val: -1 });}如果T是对一个我不想复制的大对象的引用:use std::fmt::Debug;use std::thread;struct Wrapper<T: Debug + Send> {
val: T,}fn run_thread<T: Debug + Send + 'static>(wrapper: Wrapper<T>) {
let thr = thread::spawn(move || {
println!("{:?}", wrapper.val);
});
thr.join();}fn main() {
let mut v = Vec::new();
for i in 0..1000 {
v.push(i);
}
run_thread(Wrapper { val: &v });}其结果是:error: `v` does not live long enough
--> src/main.rs:22:32
|
22 | run_thread(Wrapper { val: &v });
| ^ does not live long enough
23 | }
| - borrowed value only lives until here
|
= note: borrowed value must be valid for the static lifetime...在我真正的程序中,看起来两个Logger连接对象必须放置在Arc包装纸。客户端被要求将连接放在Arc当代码被并行化时,代码是库内部的。这尤其令人讨厌,因为连接的生存期肯定大于工作线程的生存期。我错过了什么吗?
2 回答
隔江千里
TA贡献1906条经验 获得超10个赞
Arc
sleep
Sync
Mutex
Atomic*
范围-线程池
use scoped_threadpool::Pool; // 0.1.9use std::{thread, time::Duration};fn main() { let mut vec = vec![1, 2, 3, 4, 5]; let mut pool = Pool::new(vec.len() as u32); pool.scoped(|scoped| { for e in &mut vec { scoped.execute(move || { thread::sleep(Duration::from_secs(1)); *e += 1; }); } }); println!("{:?}", vec);}
横梁
use crossbeam; // 0.6.0use std::{thread, time::Duration};fn main() { let mut vec = vec![1, 2, 3, 4, 5]; crossbeam::scope(|scope| { for e in &mut vec { scope.spawn(move |_| { thread::sleep(Duration::from_secs(1)); *e += 1; }); } }) .expect("A child thread panicked"); println!("{:?}", vec);}
人造丝
use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator}; // 1.0.3use std::{thread, time::Duration};fn main() { let mut vec = vec![1, 2, 3, 4, 5]; vec.par_iter_mut().for_each(|e| { thread::sleep(Duration::from_secs(1)); *e += 1; }); println!("{:?}", vec);}
客户端必须将连接放在 Arc
当代码被并行化时,代码是库内部的。
Arc
/ Mutex
慕森王
TA贡献1777条经验 获得超3个赞
Logger
Clone
Arc<Mutex<Connection>>
Connection
Arc
添加回答
举报
0/150
提交
取消