赞
踩
在rust中我们使用管道来实现线程之间的通信,rust中的管道实现为标准库中的channel。
示例代码如下:
- use std::sync::mpsc;
- use std::thread;
-
-
- fn main() {
- let (tx, rx) = mpsc::channel();
-
- thread::spawn(move || {
- let val = String::from("hi");
- tx.send(val).unwrap();
- });
-
- let received = rx.recv().unwrap();
- println!("Got: {}", received);
- }
我们使用了mpsc库中的channel函数来创建管道,mpsc的含义是multi producer single consumer,即多生产者单消费者。其中channel函数返回的tx表示管道发送端,rx表示管道的接收端。send方法即为数据的发送方法,revc即是数据的接收方法。
当我们使用send方法发送数据之后,数据的所有权便发生了转移。
我们看如下示例代码:
- use std::sync::mpsc;
- use std::thread;
-
- fn main() {
- let (tx, rx) = mpsc::channel();
-
- thread::spawn(move || {
- let val = String::from("hi");
- tx.send(val).unwrap();
- println!("val is {}", val);
- });
-
- let received = rx.recv().unwrap();
- println!("Got: {}", received);
- }
如果我们编译上述代码,会得到如下的结果:
- Compiling thread_channel_demo v0.1.0 (E:\CLionProjects\thread_channel_demo)
- error[E0382]: borrow of moved value: `val`
- --> src\main.rs:11:31
- |
- 9 | let val = String::from("hi");
- | --- move occurs because `val` has type `String`, which does not implement the `Copy` trait
- 10 | tx.send(val).unwrap();
- | --- value moved here
- 11 | println!("val is {}", val);
- | ^^^ value borrowed here after move
-
- For more information about this error, try `rustc --explain E0382`.
- error: could not compile `thread_channel_demo` due to previous error
通过以上的结果可以看出,在用send方法把val发送出去之后,如果再调用println方法的时候,由于val的所有权已经发生转移,所以无法通过rust编译器的所有权检查。
在使用recv方法接收数据的时候,在管道中没有数据的时候recv方法会阻塞执行线程,等待接收数据。
示例代码如下:
- use std::sync::mpsc;
- use std::thread;
- use std::time::Duration;
-
-
- fn main() {
- let (tx, rx) = mpsc::channel();
-
- thread::spawn(move || {
- let vals = vec![
- String::from("hi"),
- String::from("from"),
- String::from("the"),
- String::from("thread"),
- ];
-
- for val in vals {
- tx.send(val).unwrap();
- thread::sleep(Duration::from_secs(1));
- }
- });
-
- for received in rx {
- println!("Got: {}", received);
- }
- }
在上述示例代码中,子线程和主线程会交替执行,随着数据发送和接收。
我们使用迭代遍历的方式,从rx中接收多个数据。
我们可以使用clone方法,来创建多个发送端,即tx。
示例代码如下:
- use std::sync::mpsc;
- use std::{thread, vec};
- use std::time::Duration;
-
- fn main() {
- let (tx, rx) = mpsc::channel();
-
- let tx1 = tx.clone();
-
- thread::spawn(move || {
- let vals = vec![
- String::from("hi"),
- String::from("from"),
- String::from("the"),
- String::from("thread"),
- ];
-
- for val in vals {
- tx1.send(val).unwrap();
- thread::sleep(Duration::from_secs(1));
- }
- });
-
- thread::spawn(move || {
- let vals = vec![
- String::from("more"),
- String::from("messages"),
- String::from("for"),
- String::from("you"),
- ];
-
- for val in vals {
- tx.send(val).unwrap();
- thread::sleep(Duration::from_secs(1));
- }
- });
-
- for recevied in rx {
- println!("Got: {}", recevied);
- }
- }
我们使用clone方法创建多个tx的实例,来实现多个生产者发送数据。
执行结果如下:
- Got: hi
- Got: more
- Got: from
- Got: messages
- Got: the
- Got: for
- Got: thread
- Got: you
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。