thread_local使用很简单,只需要使用这个宏就可以了,不需要任何的use,但是释放资源的时候一定要注意,用std::ops::Drop自动释放是不可行的
下面的代码的Drop是不可行的:
use std::ops::Drop;
struct Foo;
impl Foo{
fn print(&self){
println!("print foo");
}
//fn drop(&self){
// println!("drop foo");
//}
}
thread_local!(static F:Foo = Foo);
impl Drop for Foo{
fn drop(&mut self){
println!("drop");
}
}
fn main(){
F.with(move|f:&Foo|{
f.print();
});
println!("exit");
}
编译正常,执行结果出错,提示的大致意思就是不能在thread_local销毁以后再去访问他
print foo
exit
thread '<main>' panicked at 'cannot access a TLS value during or after it is destroyed', ../src/libcore/option.rs:330
fatal runtime error: Could not unwind stack, error = 5
playpen: application terminated abnormally with signal 4 (Illegal instruction)
既然Drop自动释放不可行,那么只能自己手动释放thread_local包含的资源了,下面代码是可行的:
struct Foo;
impl Foo{
fn print(&self){
println!("print foo");
}
//为了方便就用了immutable borrow,否则main最后面调用f.drop()过不去
//如果确实需要mutable borrow的需要给Foo类型加个RefCell来包装下,访问的时候borrow_mut()就可以
fn drop(&self){
println!("drop foo");
}
}
thread_local!(static F:Foo = Foo);
fn main(){
F.with(move|f:&Foo|{
f.print();
});
F.with(|f|{
f.drop();
});
println!("exit");
}
这儿是可运行的版本,play地址:http://is.gd/AsQKMA
运行结果:
print foo
drop foo
exit
使用thread_local!的时候注意用xxx.with(|xx|{})的方式来访问,具体看main里的使用方法,比如这个例子里的变量F其实不是Foo类型,他被thread_local包装过了
我们可以直接调用F.print();
来看看编译器提示:
<anon>:28:7: 28:14 error: no method named `print` found for type `std::thread::local::LocalKey<Foo>` in the current scope
<anon>:28 F.print();
^~~~~~~
error: aborting due to previous error
playpen: application terminated with error code 101
可以明显看到F是std::thread::local::LocalKey<Foo>
类型
文档里的例子就是用的RefCell又包装了一层,需要的可以看看:
https://doc.rust-lang.org/std/thread/struct.LocalKey.html