在此代码示例中,来自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
更长。如果在线程仍在运行时退出pool
,则从线程内部引用main
拥有的main
可能导致引用已被销毁的值。
要获得pool
的所有权,您需要在每次循环执行时将其克隆,因此每个线程都有自己的副本。
在内部,Pool
是std::sync::Arc
,并且Clone
实现只是克隆Arc
。也就是说,Pool
的每个克隆只是一个递增的引用计数。创建线程后,引用计数会增加。当线程完成时,它们通过删除其Pool
来减少引用计数,并在引用计数达到零时破坏基础连接。
关于multithreading - 为什么在此克隆连接池?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66400432/