Multithreading 实施";“移动”;线程语义

Multithreading 实施";“移动”;线程语义,multithreading,rust,messaging,zero-copy,Multithreading,Rust,Messaging,Zero Copy,我想写一个函数,这样调用: send("message","address"); 其他线程正在做什么 let k = recv("address"); println!("{}",k); 查看消息 特别是,消息可能很大,因此我希望使用“move”或“zero copy”语义来发送消息 在C中,解决方案类似于: 在堆上分配消息 拥有一个全局的线程安全哈希映射,将“地址”映射到某个内存位置 发送时将指针写入内存位置,并使用信号量唤醒接收器 在接收时从内存位置读取指针,并等待信号量处理新消息 但根

我想写一个函数,这样调用:

send("message","address");
其他线程正在做什么

let k = recv("address");
println!("{}",k);
查看
消息

特别是,消息可能很大,因此我希望使用“move”或“zero copy”语义来发送消息

在C中,解决方案类似于:

  • 在堆上分配消息
  • 拥有一个全局的线程安全哈希映射,将“地址”映射到某个内存位置
  • 发送时将指针写入内存位置,并使用信号量唤醒接收器
  • 在接收时从内存位置读取指针,并等待信号量处理新消息

  • 但根据另一个SO问题,第2步是“2”。因此,我希望看到一种更为惯用的方法来解决这个问题。

    您可以自动获得此类移动语义,并通过将较大的值放入
    框中(即在堆上分配它们)来实现轻量级移动。使用
    类型ConcurrentHashMap=Mutex作为threadsafe hashmap(可以通过多种方式进行改进),您可能有:

    use std::collections::{HashMap, RingBuf};
    use std::sync::Mutex;
    
    type ConcurrentHashMap<K, V> = Mutex<HashMap<K, V>>;
    
    lazy_static! {
        pub static ref MAP: ConcurrentHashMap<String, RingBuf<String>> = {
            Mutex::new(HashMap::new())
        }
    }
    
    fn send(message: String, address: String) {
        MAP.lock()
           // find the place this message goes
           .entry(address)
           .get()
           // create a new RingBuf if this address was empty
           .unwrap_or_else(|v| v.insert(RingBuf::new()))
           // add the message on the back
           .push_back(message)
    }
    fn recv(address: &str) -> Option<String> {
         MAP.lock()
            .get_mut(address)
            // pull the message off the front
            .and_then(|buf| buf.pop_front())
    }
    
    使用std::collections::{HashMap,RingBuf};
    使用std::sync::Mutex;
    输入ConcurrentHashMap=Mutex;
    懒惰的人!{
    发布静态引用映射:ConcurrentHashMap={
    Mutex::new(HashMap::new())
    }
    }
    fn发送(消息:字符串,地址:字符串){
    MAP.lock()
    //找到这封信的目的地
    .条目(地址)
    .get()
    //如果此地址为空,请创建新的RingBuf
    .unwrap_或_else(| v | v.insert(RingBuf::new()))
    //在背面添加消息
    .推回(信息)
    }
    fn recv(地址:&str)->选项{
    MAP.lock()
    .get_mut(地址)
    //把信息从前面拉下来
    .然后(| buf | buf.pop_front())
    }
    
    该代码使用宏来实现全局hashmap(最好使用包裹
    弧的本地对象)