我如何在 Rust 中获得一个简单的可变线程局部结构?
How do I get a simple mutable thread-local struct in Rust?
我正在构建一个带有垃圾收集器的解释器。我想要一个线程本地托儿所区域和一个共享的旧区域。我在设置托儿所时遇到问题。我有:
const NurserySize : usize = 25000;
#[thread_local]
static mut NurseryMemory : [usize;NurserySize] = [0;NurserySize];
thread_local! {
static Nursery: AllocableRegion = AllocableRegion::makeLocal(unsafe{&mut NurseryMemory});
}
#[cfg(test)]
mod testMemory {
use super::*;
#[test]
fn test1() {
Nursery.with(|n| n.allocObject(10));
}
}
第一个问题是为什么我需要不安全的 - NurseryMemory 是线程本地的,所以访问不能不安全?
第二个问题是我如何实际使用它?代码位于 playground,但它无法编译,我尝试修复它似乎使它变得更糟。
1。为什么需要不安全来获取对可变 ThreadLocal 的引用?
同样的原因,你需要一个普通的可变静态不安全,
您将能够在安全代码中创建别名 mut 指针。
以下错误地创建了两个对本地可变线程的可变引用。
#![feature(thread_local)]
#[thread_local]
static mut SomeValue: Result<&str, usize> = Ok("hello world");
pub fn main() {
let first = unsafe {&mut SomeValue};
let second = unsafe {&mut SomeValue};
if let Ok(string) = first {
*second = Err(0); // should invalidate the string reference, but it doesn't
println!("{}", string) // as first and second are considered to be disjunct
}
}
first
甚至不需要成为一个可变引用,这就会成为一个问题。
2。如何修复代码?
您可以在 AllocatableRegion
周围使用 RefCell
来动态强制借用内部值。
const NurserySize : usize = 25000;
#[thread_local]
static mut NurseryMemory : [usize;NurserySize] = [0;NurserySize];
thread_local! {
static Nursery: RefCell<AllocableRegion> = RefCell::new(AllocableRegion::makeLocal(unsafe{&mut NurseryMemory}));
}
#[cfg(test)]
mod testMemory {
use super::*;
#[test]
fn test1() {
Nursery.with(|n| n.borrow_mut().allocObject(10));
}
}
我正在构建一个带有垃圾收集器的解释器。我想要一个线程本地托儿所区域和一个共享的旧区域。我在设置托儿所时遇到问题。我有:
const NurserySize : usize = 25000;
#[thread_local]
static mut NurseryMemory : [usize;NurserySize] = [0;NurserySize];
thread_local! {
static Nursery: AllocableRegion = AllocableRegion::makeLocal(unsafe{&mut NurseryMemory});
}
#[cfg(test)]
mod testMemory {
use super::*;
#[test]
fn test1() {
Nursery.with(|n| n.allocObject(10));
}
}
第一个问题是为什么我需要不安全的 - NurseryMemory 是线程本地的,所以访问不能不安全?
第二个问题是我如何实际使用它?代码位于 playground,但它无法编译,我尝试修复它似乎使它变得更糟。
1。为什么需要不安全来获取对可变 ThreadLocal 的引用?
同样的原因,你需要一个普通的可变静态不安全, 您将能够在安全代码中创建别名 mut 指针。 以下错误地创建了两个对本地可变线程的可变引用。
#![feature(thread_local)]
#[thread_local]
static mut SomeValue: Result<&str, usize> = Ok("hello world");
pub fn main() {
let first = unsafe {&mut SomeValue};
let second = unsafe {&mut SomeValue};
if let Ok(string) = first {
*second = Err(0); // should invalidate the string reference, but it doesn't
println!("{}", string) // as first and second are considered to be disjunct
}
}
first
甚至不需要成为一个可变引用,这就会成为一个问题。
2。如何修复代码?
您可以在 AllocatableRegion
周围使用 RefCell
来动态强制借用内部值。
const NurserySize : usize = 25000;
#[thread_local]
static mut NurseryMemory : [usize;NurserySize] = [0;NurserySize];
thread_local! {
static Nursery: RefCell<AllocableRegion> = RefCell::new(AllocableRegion::makeLocal(unsafe{&mut NurseryMemory}));
}
#[cfg(test)]
mod testMemory {
use super::*;
#[test]
fn test1() {
Nursery.with(|n| n.borrow_mut().allocObject(10));
}
}