Rbj*_*bjz 3 multithreading reference rust
仍在努力应对Rust的思维转变,现在我有了这个用例 - 一个多线程的配置TcpListener
:
use std::net::{TcpListener, TcpStream, ToSocketAddrs};
use std::thread;
fn main() {
serve("127.0.0.1:3333", Configuration { do_something: true });
}
//#[derive(Copy, Clone)]
pub struct Configuration {
pub do_something: bool,
}
pub fn serve<A: ToSocketAddrs>(addr: A, conf: Configuration) {
let listener = TcpListener::bind(addr).expect("bind failed");
for stream in listener.incoming() {
match stream {
Ok(stream) => {
thread::spawn(move || {
handle_client(stream, &conf);
});
}
Err(e) => {
println!("Connection failed: {}", e);
}
}
}
}
fn handle_client(stream: TcpStream, conf: &Configuration) {
if conf.do_something {
//stream....
}
}
Run Code Online (Sandbox Code Playgroud)
我很高兴TcpStream
消耗handle_client
它,这是它的目的,但为什么Configuration
必须为每个线程复制?我想只有一个副本,并与所有线程共享一个不可变的引用.那可能吗?或者也许我错过了这一点.
如果我通过引用传递,为什么我需要Copy
和Clone
特征Configuration
?这让我很困惑:
error[E0382]: capture of moved value: `conf`
--> src/main.rs:19:64
|
19 | thread::spawn(move || { handle_client(stream, &conf); });
| ------- ^^^^ value captured here after move
| |
| value moved (into closure) here
|
= note: move occurs because `conf` has type `Configuration`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)
实现Copy
(Clone
这里是偶然的)只能修复问题,因为实现它允许编译器隐式复制Configuration
结构,将复制的值传递给线程.
它需要按值传递变量,因为您告诉编译器将move
所有使用的值放入闭包中:
thread::spawn(move || {
// ^^^^ HERE
handle_client(stream, &conf);
});
Run Code Online (Sandbox Code Playgroud)
在整个宗旨的的move
关键字告诉编译器"不,不要试图推断变量是如何关闭内部使用,只需将一切".
当你move
&conf
,编译器说"好的,我将conf
进入闭包,然后参考它".
在您的情况下,您只需删除move
关键字:
thread::spawn(|| {
handle_client(stream, &conf);
});
Run Code Online (Sandbox Code Playgroud)
如果您确实需要能够使用move
关键字并传入引用,则需要移入引用:
let conf = &conf;
thread::spawn(move || {
handle_client(stream, conf);
});
Run Code Online (Sandbox Code Playgroud)
这仍然不允许您的代码编译,因为不能保证引用超过线程.在将对堆栈变量的引用传递给作用域线程时,已经详细讨论了这一点.
归档时间: |
|
查看次数: |
184 次 |
最近记录: |