如题,看着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
评论区
写评论感谢楼上二位的解答,问题已经解决,是因为match块导致lock一直没有释放的问题
其实还得看下一级作用域内有没有使用到临时变量产生的数据,如果使用到了,是你这种情况。如果没有使用到,那临时变量会在进入下一级作用域之前被drop
--
👇
viruscamp:
receiver.lock()
生成的临时变量 MutexGuard 的 drop 时机问题。简单的说,临时变量会在同层次其后的第一个
;
分号处 drop那么第二种写法,MutexGuard 有效期就包括了 job 的执行。
receiver.lock()
生成的临时变量 MutexGuard 的 drop 时机问题。简单的说,临时变量会在同层次其后的第一个
;
分号处 drop那么第二种写法,MutexGuard 有效期就包括了 job 的执行。