#read-write #cell #atomic #write #read #rw

rw-cell

从任何位置将数据写入cell,无需复制、锁定和读取同一位置

8 个版本 (4 个稳定版)

3.0.0 2024年6月14日
2.0.1 2024年3月25日
2.0.0 2024年2月14日
1.0.0 2023年6月7日
0.1.5 2023年2月11日

#165 in 并发

Download history 50/week @ 2024-04-22 21/week @ 2024-04-29 23/week @ 2024-05-06 9/week @ 2024-05-13 19/week @ 2024-05-20 38/week @ 2024-05-27 30/week @ 2024-06-03 159/week @ 2024-06-10 73/week @ 2024-06-17 24/week @ 2024-06-24 46/week @ 2024-07-01 24/week @ 2024-07-08 13/week @ 2024-07-15 50/week @ 2024-07-22 55/week @ 2024-07-29 27/week @ 2024-08-05

每月145次下载

Apache-2.0

42KB
619

Crates.io API

概述

rw_cell 允许从应用的一个位置安全地写入数据,并从另一个位置读取数据,即使写入器和读取器位于不同的线程,也无需复制/克隆和阻塞对数据的访问。

MWSR 例子

    fn main() {
    let (w0, mut r) = rw_cell::mwsr::cell(vec!["Ukraine"; 1000]);

    let w1 = r.get_writer();
    let w2 = r.get_writer();
    let w3 = r.get_writer();
    let w4 = r.get_writer();
    let w5 = r.get_writer();

    std::thread::spawn(move || loop {
        w0.write(vec!["Slovakia"; 1001])
    });

    std::thread::spawn(move || loop {
        w1.write(vec!["Estonia"; 1002])
    });

    std::thread::spawn(move || loop {
        w2.write(vec!["Czechia"; 1003])
    });

    std::thread::spawn(move || loop {
        w3.write(vec!["United Kingdom"; 1004])
    });

    std::thread::spawn(move || loop {
        w4.write(vec!["Lithuania"; 1005])
    });

    std::thread::spawn(move || loop {
        w5.write(vec!["Latvia"; 1006])
    });

    let mut slovakia        = 0;
    let mut estonia         = 0;
    let mut czechia         = 0;
    let mut united_kingdom  = 0;
    let mut lithuania       = 0;
    let mut latvia          = 0;
    let mut ukraine         = 0;

    for _ in 0..10000000usize {
        match r.read() {
            val if val.first() == Some(&"Slovakia")         => slovakia += 1,
            val if val.first() == Some(&"Estonia")          => estonia += 1,
            val if val.first() == Some(&"Czechia")          => czechia += 1,
            val if val.first() == Some(&"United Kingdom")   => united_kingdom += 1,
            val if val.first() == Some(&"Lithuania")        => lithuania += 1,
            val if val.first() == Some(&"Latvia")           => latvia += 1,
            val if val.first() == Some(&"Ukraine")          => ukraine += 1,
            val => println!("val: {:?}, Not good, but ok", val.first())
        }
    }

    println!("count Slovakia:       {}", slovakia);
    println!("count Estonia:        {}", estonia);
    println!("count Czechia:        {}", czechia);
    println!("count United Kingdom: {}", united_kingdom);
    println!("count Lithuania:      {}", lithuania);
    println!("count Latvia:         {}", latvia);
    println!("count Ukraine:        {}", ukraine);
}

SWMR 例子

fn main() -> Result<(), Box<dyn std::any::Any + Send + 'static>> {
    let mut w = rw_cell::swmr::CellDistributor::new(vec!["Ukraine".to_string(); 1000]);

    let r0 = w.get_reader();
    let r1 = w.get_reader();
    let r2 = w.get_reader();
    let r3 = w.get_reader();

    std::thread::spawn(move || loop {
        for i in 0usize.. {
            match i % 6 {
                0 => w.write(vec!["Slovakia".to_string(); 1001]),
                1 => w.write(vec!["Estonia".to_string(); 1001]),
                2 => w.write(vec!["Czechia".to_string(); 1001]),
                3 => w.write(vec!["United Kingdom".to_string(); 1001]),
                4 => w.write(vec!["Lithuania".to_string(); 1001]),
                5 => w.write(vec!["Latvia".to_string(); 1001]),
                val => println!("val: {:?}, Not good, but ok", val)
            }
        }
    });
    let count_iter = 1_000_000;
    let h0 = create_thread_read(r0, count_iter);
    let h1 = create_thread_read(r1, count_iter);
    let h2 = create_thread_read(r2, count_iter);
    let h3 = create_thread_read(r3, count_iter);

    let res0 = h0.join()?;
    let res1 = h1.join()?;
    let res2 = h2.join()?;
    let res3 = h3.join()?;

    println!("Slovakia:         {}", res0.0 + res1.0 + res2.0 + res3.0);
    println!("Estonia:          {}", res0.1 + res1.1 + res2.1 + res3.1);
    println!("Czechia:          {}", res0.2 + res1.2 + res2.2 + res3.2);
    println!("United Kingdom:   {}", res0.3 + res1.3 + res2.3 + res3.3);
    println!("Lithuania:        {}", res0.4 + res1.4 + res2.4 + res3.4);
    println!("Latvia:           {}", res0.5 + res1.5 + res2.5 + res3.5);
    println!("Ukraine:          {}", res0.6 + res1.6 + res2.6 + res3.6);

    Ok(())
}

fn create_thread_read(
    mut rw: rw_cell::swmr::CellReader<Vec<String>>,
    count_iter: usize
) -> std::thread::JoinHandle<(i32, i32, i32, i32, i32, i32, i32)> {
    let mut slovakia = 0;
    let mut estonia = 0;
    let mut czechia = 0;
    let mut united_kingdom = 0;
    let mut lithuania = 0;
    let mut latvia = 0;
    let mut ukraine = 0;

    std::thread::spawn(move || {
        for _ in 0..count_iter {
            match rw.read() {
                val if val.first() == Some(&"Slovakia".to_string())         => slovakia += 1,
                val if val.first() == Some(&"Estonia".to_string())          => estonia += 1,
                val if val.first() == Some(&"Czechia".to_string())          => czechia += 1,
                val if val.first() == Some(&"United Kingdom".to_string())   => united_kingdom += 1,
                val if val.first() == Some(&"Lithuania".to_string())        => lithuania += 1,
                val if val.first() == Some(&"Latvia".to_string())           => latvia += 1,
                val if val.first() == Some(&"Ukraine".to_string())          => ukraine += 1,
                val => println!("val: {:?}, Not good, but ok", val.first())
            }
        }
        (slovakia, estonia, czechia, united_kingdom, lithuania, latvia, ukraine)
    })
}

无运行时依赖