[英]Implementing “move” thread semantics
I want to write a function to be called like this: 我想编写一个这样的函数:
send("message","address");
Where some other thread that is doing 其他一些线程正在做什么
let k = recv("address");
println!("{}",k);
sees message
. 看到
message
。
In particular, the message may be large, and so I'd like "move" or "zero-copy" semantics for sending the message. 特别是,消息可能很大,因此我想使用“ move”或“ zero-copy”语义发送消息。
In C, the solution is something like: 在C语言中,解决方案类似于:
But according to another SO question, step #2 " sounds like a bad idea ". 但是根据另一个SO问题,步骤2“ 听起来像是个坏主意 ”。 So I'd like to see a more Rust-idiomatic way to approach this problem.
因此,我希望看到一种更符合Rust习惯的方法来解决此问题。
You get these sort of move semantics automatically, and get achieve light-weight moves by placing large values into a Box
(ie allocate them on the heap). 您会自动获得这种移动语义,并通过将较大的值放入
Box
(即在堆上分配它们)来实现轻量级的移动。 Using type ConcurrentHashMap<K, V> = Mutex<HashMap<K, V>>;
使用
type ConcurrentHashMap<K, V> = Mutex<HashMap<K, V>>;
as the threadsafe hashmap (there's various ways this could be improved), one might have: 作为线程安全的哈希表(可以通过多种方式进行改进),其中一个可能具有:
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())
}
That code is using the lazy_static!
该代码正在使用
lazy_static!
macro to achieve a global hashmap (it may be better to use a local object that wraps an Arc<ConcurrentHashMap<...>
, fwiw, since global state can make reasoning about program behaviour hard). 宏以实现全局哈希图(最好使用包装
Arc<ConcurrentHashMap<...>
fwiw的本地对象,因为全局状态会使对程序行为的推理变得困难)。 It also uses RingBuf
as a queue, so that messages bank up for a given address
. 它还将
RingBuf
用作队列,以便消息为给定address
堆积。 If you only wish to support one message at a time, the type could be ConcurrentHashMap<String, String>
, send
could become MAP.lock().insert(address, message)
and recv
just MAP.lock().remove(address)
. 如果您一次只希望支持一条消息,则类型可以为
ConcurrentHashMap<String, String>
, send
可以成为MAP.lock().insert(address, message)
并仅recv
MAP.lock().remove(address)
。
(NB. I haven't compiled this, so the types may not match up precisely.) (注意。我尚未编译此文件,因此类型可能不完全匹配。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.