< 返回版块

ziokuroi 发表于 2021-09-16 23:23

如题,看着Rust 程序设计语言 - 将单线程服务器变为多线程服务器这里的教程,试着写一个多线程的WebServer。 简单来说就是有一个名为ThreadPool的结构体维护了一些线程,如下: struct Worker { id: usize, thread: thread::JoinHandle<()>, } 线程间使用了std::sync::mpsc进行通讯,当有新的http请求进入时,ThreadPool通过sender发送Job进行分配,每一个线程都持有一个receiver的Clone let receiver = Arc::new(Mutex::new(receiver)) Arc::clone(&receiver)

问题: 教程的后面有提到,给出的代码,没有做错误处理,如下: let job = receiver.lock().unwrap().recv().unwrap(); println!("Worker {} got a job; executing.", id); job(); 于是自己写了一下错误处理,可以正常运行,如下:

let job = match receiver.lock().unwrap().recv() { Ok(job) => job, Err(err) => { eprintln!("{}", err); return; } }; println!("Worker {} got a job; executing.", id); job();

但是如果换一个写法,则所有请求都会等待同一个线程的执行,如下:

match receiver.lock().unwrap().recv() { Ok(job) => { println!("Worker {} got a job; executing.", id); job(); println!("Worker {} Finished.", id); }, Err(err) => { eprintln!("{}", err); } };

为什么会这样?求各位彦祖解答,不胜感激! 项目的代码已上传至GitHub

评论区

写评论
作者 ziokuroi 2021-09-17 15:42

感谢楼上二位的解答,问题已经解决,是因为match块导致lock一直没有释放的问题

jcsora 2021-09-17 10:25

其实还得看下一级作用域内有没有使用到临时变量产生的数据,如果使用到了,是你这种情况。如果没有使用到,那临时变量会在进入下一级作用域之前被drop

--
👇
viruscamp: receiver.lock() 生成的临时变量 MutexGuard 的 drop 时机问题。

简单的说,临时变量会在同层次其后的第一个;分号处 drop

那么第二种写法,MutexGuard 有效期就包括了 job 的执行。

viruscamp 2021-09-17 00:16

receiver.lock() 生成的临时变量 MutexGuard 的 drop 时机问题。

简单的说,临时变量会在同层次其后的第一个;分号处 drop

那么第二种写法,MutexGuard 有效期就包括了 job 的执行。

1 共 3 条评论, 1 页