#thread #threading #container #data #variables #safe #thread-unsafe

线程安全

允许线程不安全对象实现线程安全的容器

3 个版本

0.1.2 2021 年 8 月 21 日
0.1.1 2021 年 7 月 2 日
0.1.0 2021 年 6 月 19 日

并发 中排名 #1144

MIT/Apache

16KB
242 行(不含注释)

线程安全

此 crate 实现了一个简单的容器,允许线程不安全变量在只要它们只从原始线程直接访问的情况下跨线程传递。此 crate 允许 breadthread 中不包含任何不安全代码。

许可证

此 crate 在 MIT 和 Apache 2.0 许可证下双许可,就像 Rust 本身一样。


lib.rs:

假设你有一些线程不安全的数据。出于某种原因,它不能在它起源的线程之外使用。这种线程不安全的数据是更大的数据结构的一部分,该数据结构确实需要在其他线程之间传递。

ThreadSafe 包含只能在创建它的线程中使用的数据。当尝试获取内部数据的引用时,它会检查来源线程。

ThreadKey

ThreadKeyThreadId 的包装,但是 !Send。这允许一个人证明当前线程具有给定的 ThreadId,而无需通过 thread::current().id()

示例

use std::{cell::Cell, sync::{Arc, atomic}, thread};
use thread_safe::ThreadSafe;

#[derive(Debug)]
struct InnerData {
    counter: atomic::AtomicUsize,
    other_counter: ThreadSafe<Cell<usize>>,
}

fn increment_data(data: &InnerData) {
    data.counter.fetch_add(1, atomic::Ordering::SeqCst);
    if let Ok(counter) = data.other_counter.try_get_ref() {
        counter.set(counter.get() + 1);
    }
}

let data = Arc::new(InnerData {
    counter: atomic::AtomicUsize::new(0),
    other_counter: ThreadSafe::new(Cell::new(0)),
});

let mut handles = vec![];

for _ in 0..10 {
    let data = data.clone();
    handles.push(thread::spawn(move || increment_data(&data)));
}

increment_data(&data);

for handle in handles {
    handle.join().unwrap();
}

let data = Arc::try_unwrap(data).unwrap();
assert_eq!(data.counter.load(atomic::Ordering::Relaxed), 11);
assert_eq!(data.other_counter.get_ref().get(), 1);

无运行时依赖