4 个版本
0.1.3 | 2019 年 12 月 19 日 |
---|---|
0.1.2 | 2019 年 10 月 25 日 |
0.1.1 | 2019 年 10 月 25 日 |
0.1.0 | 2019 年 10 月 25 日 |
1100 在 Rust 模式 中
61,952 每月下载量
在 4 个 软件包中使用 (直接使用 3 个)
27KB
390 行
基于 OS 的线程本地存储
此软件包提供了一个 ThreadLocal
类型,作为 std::thread_local!
的替代方案,允许按对象进行线程本地存储,同时提供类似的 API。它始终使用由操作系统提供的线程本地存储原语。
在 Unix 系统上,使用基于 pthread 的线程本地存储。
在 Windows 上,使用纤维本地存储。当纤维未被使用时,它类似于线程本地存储,但在创建纤维后(例如,使用 winapi::um::winbase::CreateFiber
)还提供按纤维的值。
thread_local
软件包是另一个提供按对象线程本地存储的软件包的示例,具有不同的 API 和不同的功能,但与这个软件包相比,性能开销更大。
示例
这与 std::thread::LocalKey
文档中的示例相同,但已调整以使用 ThreadLocal
。要在 static
上下文中使用它,需要懒加载初始化器,例如 once_cell::sync::Lazy
或 lazy_static!
。
use std::cell::RefCell;
use std::thread;
use once_cell::sync::Lazy;
use os_thread_local::ThreadLocal;
static FOO: Lazy<ThreadLocal<RefCell<u32>>> =
Lazy::new(|| ThreadLocal::new(|| RefCell::new(1)));
FOO.with(|f| {
assert_eq!(*f.borrow(), 1);
*f.borrow_mut() = 2;
});
// each thread starts out with the initial value of 1
let t = thread::spawn(move || {
FOO.with(|f| {
assert_eq!(*f.borrow(), 1);
*f.borrow_mut() = 3;
});
});
// wait for the thread to complete and bail out on panic
t.join().unwrap();
// we retain our original value of 2 despite the child thread
FOO.with(|f| {
assert_eq!(*f.borrow(), 2);
});
具有范围线程和按对象线程本地存储的相同示例的变体
use std::cell::RefCell;
use crossbeam_utils::thread::scope;
use os_thread_local::ThreadLocal;
struct Foo {
data: u32,
tls: ThreadLocal<RefCell<u32>>,
}
let foo = Foo {
data: 0,
tls: ThreadLocal::new(|| RefCell::new(1)),
};
foo.tls.with(|f| {
assert_eq!(*f.borrow(), 1);
*f.borrow_mut() = 2;
});
scope(|s| {
// each thread starts out with the initial value of 1
let foo2 = &foo;
let t = s.spawn(move |_| {
foo2.tls.with(|f| {
assert_eq!(*f.borrow(), 1);
*f.borrow_mut() = 3;
});
});
// wait for the thread to complete and bail out on panic
t.join().unwrap();
// we retain our original value of 2 despite the child thread
foo.tls.with(|f| {
assert_eq!(*f.borrow(), 2);
});
}).unwrap();
依赖项
~215KB