#thread #swap #ownership #data #control

swapper

线程间交换数据所有权

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 并发

Download history 1165/week @ 2024-04-08 901/week @ 2024-04-15 1143/week @ 2024-04-22 1411/week @ 2024-04-29 1049/week @ 2024-05-06 970/week @ 2024-05-13 1493/week @ 2024-05-20 1311/week @ 2024-05-27 720/week @ 2024-06-03 1200/week @ 2024-06-10 1780/week @ 2024-06-17 1445/week @ 2024-06-24 1562/week @ 2024-07-01 1868/week @ 2024-07-08 1321/week @ 2024-07-15 1273/week @ 2024-07-22

6,117 每月下载量

MPL-2.0 许可证

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(),
       }
   }
}

无运行时依赖