为什么要把Connection pool克隆到这里?

Why is the Connection pool cloned here?

在此代码示例中,来自 Github page of r2d2:

fn main() {
    let manager = r2d2_foodb::FooConnectionManager::new("localhost:1234");
    let pool = r2d2::Pool::builder()
        .max_size(15)
        .build(manager)
        .unwrap();

    for _ in 0..20 {
        let pool = pool.clone();
        thread::spawn(move || {
            let conn = pool.get().unwrap();
        })
    }
}

为什么要在循环中克隆 Pool 结构?

这是因为循环内产生的线程需要获得 pool 的所有权,因为每个线程可以 运行 的时间长于 main。从线程内部引用 main 拥有的 pool 可能会导致引用一个已经被销毁的值,如果 main 在线程仍在 运行ning 时退出。

获取 pool 的所有权需要您在每次循环执行时克隆它,因此每个线程都有自己的副本。

在内部,Pool 是一个 std::sync::ArcClone 实现只是克隆了 Arc。也就是说,Pool 的每个克隆只是一个递增的引用计数。随着线程的创建,引用计数会增加。当线程完成时,它们通过删除 Pool 来减少引用计数,当引用计数达到零时破坏底层连接。