Rust : evmap库多读多写尝试

先用evmap上的例子来尝试
Cargo.toml

evmap = "10.0.2"

一、模式探讨

1、多写多读模式一:


use parking_lot::*;
use std::thread;
use std::sync::{Arc, Mutex};
use std::time;
use std::collections::{HashMap};
extern crate evmap;
use evmap::{ReadHandle, WriteHandle};

fn main(){
    let (book_reviews_r, mut book_reviews_w) = evmap::new();

   //多写
   let writer_n =4;
    let w = Arc::new(Mutex::new(book_reviews_w));
    let writers: Vec<_> = (0..writer_n).map(|i| {
        let w = w.clone();
        thread::spawn(move || {
            let mut w = w.lock().unwrap();
            w.insert(i.to_string(), i); // 数据的结构,key,value
            w.refresh();
        })
    }).collect();
    // 多读
    let reader_n =50;
    let readers: Vec<_> = (0..reader_n).map(|_| {
        let r = book_reviews_r.clone();
        thread::spawn(move || {
            loop {
                let l = r.len();
                if l == 0 {
                    thread::yield_now();// 放弃
                } else {
                    println!("--------------------------- start");
                    println!("r ---> : {:?}", l);
                    for (book, reviews) in &r.read().unwrap() {
                          for review in reviews {
                              println!("{}: \"{}\"", book, review);
                          }
                    } 
                    println!("--------------------------- end");
                    break;
                }
            }
        })
    }).collect();

    std::thread::sleep(std::time::Duration::from_secs(1000)); // 需要在主线程上停留足够时间
    
}

在这种情况下,读是完全一样的。感觉是已经写完之后,再去读的。

2、多写多读模式2:边写边读模式

为了更加真实,在读和写放在一个循还不同的二个线程中。

fn main(){
    let (book_reviews_r, mut book_reviews_w) = evmap::new();
    let w = Arc::new(Mutex::new(book_reviews_w));
    for i in 0..5{
        let r = book_reviews_r.clone();
        thread::spawn(move || {
            loop {
                let l = r.len();
                if l == 0 {
                    thread::yield_now();// 放弃
                } else {
                    println!("--------------------------- start");
                    println!("r ---> : {:?}", l);
                    for (book, reviews) in &r.read().unwrap() {
                          for review in reviews {
                              println!("{}: \"{}\"", book, review);
                          }
                    } 
                    println!("--------------------------- end");
                    break;
                }
            }
        });
        let w = w.clone();
        thread::spawn(move || {
            let mut w = w.lock().unwrap();
            w.insert(i.to_string(), i);
            w.refresh();
        });

    }
    std::thread::sleep(std::time::Duration::from_secs(100));
    
}

可以看到,在这种情况下,更象是是边写边读的。
在这里插入图片描述
大家想想看,有什么问题?r和真实的不一样!

3、模式3


fn main(){

    let (book_reviews_r, mut book_reviews_w) = evmap::new();
    let w = Arc::new(Mutex::new(book_reviews_w));
    for i in 0..5{
       // 先放写
        let w = w.clone();
        thread::spawn(move || {
            let mut w = w.lock().unwrap();
            w.insert(i.to_string(), i);
            w.refresh();
        });
       //后放读
        let r = book_reviews_r.clone();
        thread::spawn(move || {
            loop {
                let l = r.len();
                if l == 0 {
                    thread::yield_now();// 放弃
                } else {
                    // the reader will either see all the reviews,
                    // or none of them, since refresh() is atomic.
                    //w.refresh();
                    println!("--------------------------- start");
                    println!("r ---> : {:?}", l);
                    for (book, reviews) in &r.read().unwrap() {
                          for review in reviews {
                              println!("{}: \"{}\"", book, review);
                          }
                    } 
                    println!("--------------------------- end");
                    break;
                }
            }
        });
    }
    std::thread::sleep(std::time::Duration::from_secs(100));
    
}

在这里插入图片描述上面看到的结果,没毛病了。其实不然,…
在这里插入图片描述


use parking_lot::*;
use std::thread;
use std::sync::{Arc, Mutex};
use std::time;
use std::collections::{HashMap};
extern crate evmap;
use evmap::{ReadHandle, WriteHandle,ReadGuard,Values};
use std::sync::RwLock;
use std::hash::{BuildHasher, Hash};
#[macro_use]
extern crate lazy_static;

lazy_static! {
    static ref HASHMAP: HashMap<u32,String> = {
        let mut m = HashMap::new();
        m.insert(0, "foo".into());
        m.insert(1, "bar".into());
        m.insert(2, "baz".into());
        m
    };
    //static ref COUNT: usize = HASHMAP.len();
    //static ref NUMBER: u32 = times_two(21);
}



// 关于读值
fn main(){

    let (book_reviews_r, mut book_reviews_w) = evmap::new::<String,i32>();
    //book_reviews_w => WriteHandle { epochs: Mutex { data: Slab { len: 2, cap: 2 } }, w_handle: Some(Inner { data: {}, meta: (), ready: true }), oplog: [], swap_index: 0, r_handle: ReadHandle}
    //book_reviews_r => ReadHandle { epochs: Mutex { data: Slab { len: 2, cap: 2 } }, epoch: 0, my_epoch: 0 }
    let w = Arc::new(Mutex::new(book_reviews_w));
    println!("start writing.....including reading....");
    for i in 0..10{
        let w = w.clone();
        let r = book_reviews_r.clone();
        let code = "IF0001".to_string();
        thread::spawn(move || {
            let mut w = w.lock().unwrap();
            let l = r.len();
            match l {
                0 => {
                    println!("0 => l:{:?}",l);
                    let code = code.clone();
                    w.insert(code, i);    
                    println!("thread :{:?} => 0, insert =>{:?}",i,i); 
                    w.refresh();              
                },
                _=>{
                    println!("l:{:?}",l);
                    w.refresh();
                    let value = r.get(&code);//=> get => Option<ReadGuard<'rh, Values<V, S>>>
                    
                    match value {
                        Some(rgd) =>{ //ReadGuard<'rh, Values<V, S>>
                            let mut v = (&*rgd).clone(); // 读值
                            println!("value =>{:?}",v);
                            w.insert(code.clone(),i);
                            w.refresh();
                        },
                        None =>{
                            println!("none=>");
                            w.insert(code, i);   
                            w.refresh();  
                        }
                    } 
                },

            }
        });
        
    }
    std::thread::sleep(std::time::Duration::from_secs(100));    
}

二、关于重要的方法

book_reviews_r 可用的方法有:
read();
get(),
clone();
len()
get_meta()
contains_key()

mut book_reviews_w可用的方法有:
refresh(),
insert(),
clone()
remove_value()
remove_keys()
retain()
remove_entry()
update()
clear()
extend()

r.read().unwrap().keys()
r.read().unwrap().values()

具体见:
https://github.com/jonhoo/rust-evmap/blob/master/tests/lib.rs

fn main(){
    //run::strategy_run().unwrap();   
    //std::thread::sleep(std::time::Duration::from_secs(10000));

    let (book_reviews_r, mut book_reviews_w) = evmap::new();
    let w = Arc::new(Mutex::new(book_reviews_w));
    for i in 0..5{
        let w = w.clone();
        thread::spawn(move || {
            let mut w = w.lock().unwrap();
            let mut v = Vec::new();
            v.push(i);
            w.insert(i.to_string(), v);
            w.update(i.to_string(), vec![i,i+1]);
            w.refresh();
        });

        let r = book_reviews_r.clone();
        //r.refresh();
        let l = r.len();

        println!("r ---> : {:?}", l);
        thread::spawn(move || {
            loop {
                println!("--------------------------- start");
                for (book, reviews) in &r.read().unwrap() {
                    println!("{:?}: \"{:?}\"", book, reviews);
                } 
                println!("--------------------------- end");
                break;
            }
        });
    }
    std::thread::sleep(std::time::Duration::from_secs(100));    
}


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值