thread_local!
可由该工作线程上的任务使用的类型(
T
在下面的例子中)。这个类的主要目的是
T型
不需要
Send
,因为它将通过工厂方法在每个工作线程上本地构造
是
我的用例是在一个
!Send
T型
extern crate threadpool;
use std::sync::mpsc::channel;
use std::sync::Arc;
// A RemoteResource is a threadpool that maintains a threadlocal ?Send resource
// on every pool in the thread, which tasks sent to the pool can reference.
// It can be used e.g., to manage a pool of database connections.
struct RemoteResource<T, M>
where
M: 'static + Send + Sync + Fn() -> T,
{
pool: threadpool::ThreadPool,
make_resource: Arc<M>,
}
impl<T, M> RemoteResource<T, M>
where
M: Send + Sync + Fn() -> T,
{
pub fn new(num_workers: usize, make_resource: M) -> Self {
RemoteResource {
pool: threadpool::ThreadPool::new(num_workers),
make_resource: Arc::new(make_resource),
}
}
pub fn call<F, R>(&mut self, f: F) -> R
where
R: 'static + Send,
F: 'static + ::std::marker::Send + FnOnce(&mut T) -> R,
{
let (tx, rx) = channel();
let maker = self.make_resource.clone();
self.pool.execute(move || {
use std::cell::RefCell;
thread_local!{
static UNSENDABLE_TYPE: RefCell<Option<T>> = RefCell::new(None)
}
UNSENDABLE_TYPE.with(|it| {
let mut mine = it.borrow_mut();
if mine.is_none() {
*mine = Some(maker());
}
if let Some(ref mut mine) = *mine {
let res = f(mine);
tx.send(res).unwrap();
return ();
}
unreachable!()
});
});
rx.recv().unwrap()
}
}
(
Playground
)
不幸的是,我不能让我的代码打字检查时,我抽象了
T型
:
error[E0401]: can't use type parameters from outer function
--> src/lib.rs:38:56
|
17 | impl<T, M> RemoteResource<T, M>
| - type variable from outer function
...
28 | pub fn call<F, R>(&mut self, f: F) -> R
| ---- try adding a local type parameter in this method instead
...
38 | static UNSENDABLE_TYPE: RefCell<Option<T>> = RefCell::new(None)
| ^ use of type variable from outer function
T型
进入之内
call
,然后我得到一个“shadowd type variable”错误。如果我介绍一种新的类型
U
呼叫
,正好是我已经添加的地方。在我看来,第二件事就像编译器中的一个bug(如果你对此很好奇,
here's the playground
).