如何在Rust结构内部创建线程局部变量?

问题描述 投票:0回答:1

我需要一个线程局部变量,理想情况下存储在一个结构中,该结构当前存储了程序的大部分全局状态。

我看到的第一种方法是使用thread_local!宏,但是我想将此线程保持在状态结构内的本地。

我可以看到的第二种方法是在线程和线程局部变量的值之间使用一个HashMap<Thread,MyThreadLocalData>或类似值。然后,我将有一个使用thread::current查找适当值的吸气剂。

我要提到的最后一个要求是,并非给定程序中的所有线程都由Rust代码创建,但是Rust代码可以在任何线程上运行,因此解决方案对此应该是健壮的。

是否有最佳实践方法?也许有threadId可以让我使用简单的Vec而不是HashMap(和/或避免散列开销)?有图书馆吗?

另一个选择是修改可以在多线程上下文中使用的每个函数的参数,以同时采用状态结构和线程局部状态结构,但是,这对于不由Rust创建的线程不容易使用。

multithreading rust thread-local
1个回答
2
投票

可以在结构中使用线程局部变量,只需将其放置在impl块中即可:

use std::cell::RefCell;

struct Foo;
impl Foo {
    thread_local! {
        // Could add pub to make it public to whatever Foo already is public to.
        static FOO: RefCell<usize> = RefCell::new(0);
    }
}

并且可以使用Foo::FOO进行访问:

Foo::FOO.with(|x| println!("{:?}", x));

Playground但是请注意,必须使用它前面的Foo::来访问它,因为它不是字段,而是关联的static

也可以通过存储对它的引用来完成:

use std::cell::RefCell;
use std::thread::LocalKey;

thread_local! {
    // Note lack of pub
    static FOO: RefCell<usize> = RefCell::new(0);
}
struct Bar {
    // Visibility here changes what can see `foo`.
    foo: &'static LocalKey<RefCell<usize>>,
    // Rest of your data.
}
impl Bar {
    fn constructor() -> Self {
        Self {
            foo: &FOO,
            // Rest of your data.
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.