zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Rust 中 #[thread_local] 的drop方法不被调用

2023-03-07 09:49:50 时间

原文链接: https://drmingdrmer.github.io/tips/#/page/rust-thread-local-drop

Rust 中有2种方法声明 thread-local[2] 变量: 使用标准库的宏 thread_local!{}[3] 或使用 attribute #[thread_local][4], 经在databend的好友 winter[5], 提醒, 这里有个不rust的地方, #[thread_local] 按官方说法是被"translates directly to the thread_local attribute in LLVM", 线程销毁时不会调用它的drop方法, 但宏声明的thread-local变量没问题:

使用宏 thread_local!{...} 定义, 正常调用了 drop:

struct Foo(usize);
impl Drop for Foo {
    fn drop(&mut self) { println!("dropped"); }
}

thread_local! {
    static MACRO_TLS: std::cell::RefCell<Foo> = std::cell::RefCell::new(Foo(0));
}

fn main() {
    let _ = std::thread::spawn(|| unsafe {
        MACRO_TLS.with(|f| {
            println!("foo: {}", f.borrow_mut().0);
        });
    })
    .join();
}
// Output:
// foo: 0
// dropped

使用 attribute #[thread_local] 定义, 没有调用 drop:

#![feature(thread_local)]
struct Foo(usize);
impl Drop for Foo {
    fn drop(&mut self) { println!("dropped"); }
}

#[thread_local]
static mut ATTR_TLS: Foo = Foo(0);

fn main() {
    let _ = std::thread::spawn(|| unsafe {
        println!("foo: {}", ATTR_TLS.0);
    })
    .join();
}
// Output:
// foo: 0

引用链接

[1] 原文链接: https://drmingdrmer.github.io/tips/#/page/rust-thread-local-drop [2] thread-local: https://en.wikipedia.org/wiki/Thread-local_storage [3] thread_local!{}: https://doc.rust-lang.org/std/macro.thread_local.html [4] #[thread_local]: https://doc.rust-lang.org/beta/unstable-book/language-features/thread-local.html [5] winter: https://github.com/zhang2014