【发布时间】:2020-07-31 05:55:46
【问题描述】:
我对如何设计这个问题摸不着头脑。基本上,我想实现一个工作池——有点类似于来自the book 的ThreadPool,但有一点不同。在书中,他们只是传递了一个闭包,让池中的一个线程运行。但是,我希望池中的每个线程都有一些状态。让我解释一下:
use std::sync::{mpsc, Arc, Mutex};
use std::thread;
struct Job {
x: usize,
}
struct WorkerPool {
sender: mpsc::Sender<Job>,
workers: Vec<Worker>,
}
impl WorkerPool {
fn new(num_workers: usize) -> WorkerPool {
let mut workers = Vec::with_capacity(num_workers);
let (sender, receiver) = mpsc::channel();
let receiver = Arc::new(Mutex::new(receiver));
for id in 0..num_workers {
workers.push(Worker::new(id, receiver.clone()));
}
WorkerPool { sender, workers }
}
}
struct Worker {
id: usize,
thread: Option<thread::JoinHandle<()>>,
receiver: Arc<Mutex<mpsc::Receiver<Job>>>,
}
impl Worker {
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
Worker {
id,
thread: None,
receiver,
}
}
fn start(&mut self) {
self.thread = Some(thread::spawn(move || loop {
let job = self.receiver.lock().unwrap().recv().unwrap();
self.add_to_id(job.x);
}));
}
pub fn add_to_id(&self, x: usize) {
println!("The result is: {}", self.id + x);
}
}
我的每个Workers 都有一个 id,它的工作是接受一个包含一个数字的 Job,并打印它的 id 加上那个数字(这当然是一个简化版本;在我的真实用例,每个工作人员都有一个 HTTP 客户端和其他一些状态)。在我看来很简单的问题,但显然上面的代码无法编译。
我意识到Worker::start 中的代码不可能工作,因为它正在将self 移动到线程闭包中,同时我试图分配给self。
问题是,我还能如何访问线程的“父”结构中的字段?
我能否以某种方式将线程闭包的生命周期限制为结构的生命周期? (很确定答案是否定的,因为闭包必须是'static)。或者反过来,我必须在这里制作'static 的所有内容吗?
【问题讨论】:
标签: rust