5 个版本
使用旧的 Rust 2015
0.1.0 | 2017年10月10日 |
---|---|
0.0.4 | 2017年4月26日 |
0.0.3 | 2017年4月26日 |
0.0.2 | 2017年4月25日 |
0.0.1 | 2017年4月25日 |
#759 in 并发
6,117 每月下载量
9KB
61 行
swapper
在 Rust 中在线程间交换数据所有权。
此 crate 允许线程在不进入暂时无所有权的状态的情况下交换数据所有权。
let (ab, ba) = swapper::swapper();
thread::spawn(move || {
let mut a = String::from("hello");
ab.swap(&mut a).unwrap();
assert_eq!(a, "world");
});
let mut b = String::from("world");
ba.swap(&mut b).unwrap();
assert_eq!(b, "hello");
lib.rs
:
原子交换所有权的并发控制。
线程池的一个常见模式是每个线程拥有一个令牌,有时线程需要交换令牌。一个骨架示例是
struct Token;
enum Message {
// Messages go here
};
struct Thread {
sender_to_other_thread: Sender<Message>,
receiver_from_other_thread: Receiver<Message>,
token: Token,
}
impl Thread {
fn swap_token(&mut self) {
// This function should swap the token with the other thread.
}
fn handle(&mut self, message: Message) {
match message {
// Message handlers go here
}
}
fn run(&mut self) {
loop {
let message = self.receiver_from_other_thread.recv();
match message {
Ok(message) => self.handle(message),
Err(_) => return,
}
}
}
}
使用 Rust 的通道,令牌的所有权首先从线程传递到通道,然后到另一个线程,导致线程暂时无令牌的状态。通常为了解决这个问题,线程存储一个 Option<Token>
而不是 Token
enum Message {
SwapToken(Token, Sender<Token>),
};
struct Thread {
sender_to_other_thread: Sender<Message>,
receiver_from_other_thread: Receiver<Message>,
token: Option<Token>, // ANNOYING Option
}
impl Thread {
fn swap_token(&mut self) {
let (sender, receiver) = mpsc::channel();
let token = self.token.take().unwrap();
self.sender_to_other_thread.send(Message::SwapToken(token, sender));
let token = receiver.recv().unwrap();
self.token = Some(token);
}
fn handle(&mut self, message: Message) {
match message {
Message::SwapToken(token, sender) => {
let token = mem::replace(&mut self.token, Some(token)).unwrap();
sender.send(token).unwrap();
}
}
}
}
此 crate 提供了一个在线程间交换所有权的同步原语。API 与通道类似,不同之处在于没有分离的 send(T)
和 recv():T
方法,只有一个 swap(T):T
,它交换一个由一个线程拥有的 T
和另一个线程拥有的 T
。例如,它允许实现始终拥有令牌的线程池。
enum Message {
SwapToken(Swapper<Token>),
};
struct Thread {
sender_to_other_thread: Sender<Message>,
receiver_from_other_thread: Receiver<Message>,
token: Token,
}
impl Thread {
fn swap_token(&mut self) {
let (our_swapper, their_swapper) = swapper::swapper();
self.sender_to_other_thread.send(Message::SwapToken(their_swapper));
our_swapper.swap(&mut self.token).unwrap();
}
fn handle(&mut self, message: Message) {
match message {
Message::SwapToken(swapper) => swapper.swap(&mut self.token).unwrap(),
}
}
}