Rust

时间:2016-05-28 22:09:35

标签: rust

我正在尝试实现一个非常天真的线程池模型。现在,线程池的职责是:

  • 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
}

Rust Play

我尝试了几件事,比如使用RefCell,但我开始失去很多生命周期参数错误。

这是一个精简版本,我希望这是最简单的解释。

1 个答案:

答案 0 :(得分:3)

  

我需要能够从任何线程

中调用线程池的方法

这要求线程池数据采用互斥机制,如MutexRwLockRefCell不适合多线程情况,请参阅{{3} })。此外,每个线程必须保持对线程池数据的引用,因为线程池存储线程,这将创建the book。要解决此问题,我们可以将线程池​​数据放在problem中,并在每个线程中存储Arc引用。请注意,我们使用弱引用来避免Weak

  

有效地最终改变了一个或多个线程(调用者和目标)。

这要求线程数据处于互斥机制中。要最终确定需求,请注意,由于线程池数据位于Mutex中,我们无法返回对线程的引用(这需要保持线程池数据被锁定),因此我们还将线程数据放入{{1 }}

以下是使用Arcreference cycles)实施的示例:

Mutex