我正在尝试实现一个非常天真的线程池模型。现在,线程池的职责是:
create
新线程并返回对它的引用我的主要问题是上面的要求迫使我让线程池保留HashMap<Id, Thread>
个线程,但在创建线程时也提供对线程的引用。
最重要的是,我需要能够从任何有效地最终改变一个或多个线程(调用者和目标)的线程内部调用线程池的方法。
这是一个非功能性实现:
use std::collections::HashMap;
use std::cell::RefCell;
type Id = u32;
type ThreadPoolRef = RefCell<ThreadPool>;
#[derive(Debug)]
struct ThreadPool {
pool: HashMap<Id, RefCell<Thread>>,
id_count: Id
}
impl ThreadPool {
fn new() -> ThreadPool {
ThreadPool {
pool: HashMap::new(),
id_count: 1
}
}
fn create(&mut self) -> &RefCell<Thread> {
let thread: RefCell<Thread> =
RefCell::new(
Thread::new(self.id_count, RefCell::new(self))
);
self.id_count = self.id_count + 1;
self.pool.insert(self.id_count, thread);
self.pool.get(&self.id_count).unwrap()
}
}
#[derive(Debug, Clone)]
struct Thread {
id: Id,
pool: ThreadPoolRef
}
impl Thread {
fn new(id: Id, pool: ThreadPoolRef) -> Thread {
Thread {
id: id,
pool: pool
}
}
}
fn main() {
let thread_pool = ThreadPool::new();
let thread1 = thread_pool.create();
let thread2 = thread_pool.create();
// The final goal is to call thread1.method()
// that mutates thread1 and calls thread_pool.method2()
// which in turn will call thread2.method3() that will effectively
// mutate thread 2
}
我尝试了几件事,比如使用RefCell
,但我开始失去很多生命周期参数错误。
这是一个精简版本,我希望这是最简单的解释。
答案 0 :(得分:3)
我需要能够从任何线程
中调用线程池的方法
这要求线程池数据采用互斥机制,如Mutex
或RwLock
(RefCell
不适合多线程情况,请参阅{{3} })。此外,每个线程必须保持对线程池数据的引用,因为线程池存储线程,这将创建the book。要解决此问题,我们可以将线程池数据放在problem中,并在每个线程中存储Arc
引用。请注意,我们使用弱引用来避免Weak
。
有效地最终改变了一个或多个线程(调用者和目标)。
这要求线程数据处于互斥机制中。要最终确定需求,请注意,由于线程池数据位于Mutex
中,我们无法返回对线程的引用(这需要保持线程池数据被锁定),因此我们还将线程数据放入{{1 }}
以下是使用Arc
(reference cycles)实施的示例:
Mutex