旅游类网站模板免费下载,电子工程设计网站,百度安装免费下载,策划营销Channel允许在Rust中创建一个消息传递渠道#xff0c;它返回一个元组结构体#xff0c;其中包含发送和接收端。发送端用于向通道发送数据#xff0c;而接收端则用于从通道接收数据。不能使用可变变量的方式#xff0c;线程外面修改了可变变量的值#xff0c;线程里面是拿不…
Channel允许在Rust中创建一个消息传递渠道它返回一个元组结构体其中包含发送和接收端。发送端用于向通道发送数据而接收端则用于从通道接收数据。不能使用可变变量的方式线程外面修改了可变变量的值线程里面是拿不到最新的值的。 不可用方式
is_loading在主线程里面通过参数传递给子线程等待5秒之后主线程里面的is_loading修改为false但是子线程里面获取不到最新的值是由于所有权和线程安全性的限制所导致的。所以会导致子线程一直运行
use std::io::{self, Write};
use std::thread;
use std::time::Duration;fn main() {let mut is_loading true;// creat close package must use move to get is_loadingthread::spawn(move || { sub_loading(is_loading) });// sleep 3 second then stop loadingthread::sleep(Duration::from_secs(5));// set loading stopis_loading false;loop {thread::sleep(Duration::from_millis(250));print!(build done);}
}fn sub_loading(flag: bool) {let loading_chars vec![-, \\, |, /];let mut index 0;// cant get newe valuewhile *flag {print!(\rLoading {} {} , flag, loading_chars[index]);io::stdout().flush().unwrap();index (index 1) % loading_chars.len();thread::sleep(Duration::from_millis(250));}
} Channel通道说明
每个channel由两部分组成发送端Sender和接收端Receiver。 发送端用于向channel发送消息而接收端则用于接收这些消息。这种机制允许线程之间的安全通信避免了共享内存的复杂性和潜在的数据竞争问题。 (通过通信来共享内存,而非通过共享内存来通信) Rust的channel为线程间通信提供了一种安全、简单的方式是构建并发应用的基础工具之一。channel是Rust标准库的一部分自Rust 1.0版本以来就包含了这个功能。随着Rust语言和标准库的发展channel的实现和API可能会有所改进但其基本概念和用法保持一致。
基本步骤如下
创建: 使用std::sync::mpsc::channel()函数创建一个新的channel这个函数返回一个包含发送端(Sender)和接收端(Receiver)的元组。
发送: 使用发送端的send方法发送消息。send方法接受一个消息值如果接收端已经被丢弃会返回一个错误。
接收: 使用接收端的recv方法接收消息。recv会阻塞当前线程直到一个消息可用或者channel被关闭。
最简单的一个使用demo
use std::sync::mpsc;
use std::thread;fn main() {// 创建一个通道let (sender, receiver) mpsc::channel();// 在主线程中发送数据let data 42;sender.send(data).unwrap();// 创建子线程来接收数据let child_thread thread::spawn(move || {let received_data receiver.recv().unwrap();println!(Received data in child thread: {}, received_data);});child_thread.join().unwrap();
}在Rust中如果你想停止一个由thread::spawn创建的线程你不能直接停止它因为Rust没有提供直接的方式来停止线程。但是你可以通过通信来请求线程优雅地停止运行。
如果想使用一种方式让主线程控制子线程停止就可以使用channel通道
use std::sync::mpsc;
use std::thread;
use std::time::Duration;fn main() {let (tx, rx) mpsc::channel();let child_thread thread::spawn(move || {loop {// 检查是否收到停止信号if let Ok(_) rx.try_recv() {println!(线程收到停止信号正在退出...);break; // 退出循环线程结束}// 执行线程的工作println!(sub child thread is ruing);// 为了演示让线程休眠一会儿thread::sleep(Duration::from_secs(1));}println!(线程已退出。);});// 主线程等6秒模拟耗时操作thread::sleep(Duration::from_secs(6));// 假设6秒后需要停止线程tx.send(()).unwrap(); // 发送停止信号// 等待线程退出child_thread.join().unwrap();
}运行结果: 注意事项
recv方法是阻塞的即 它会阻塞当前线程, 直到从通道中接收到消息。 线程在调用rx.recv().unwrap()时会阻塞 等待消息的到来。一旦主线程通过tx.send(msg).unwrap();发送了消息主线程会接收到这个消息并继续执行之后程序才会正常退出。
try_recv尝试在不阻塞的情况下返回此接收器上的挂起值。此方法永远不会为了等待数据可用而阻止调用方。相反它将始终立即返回并可能选择通道上的挂起数据。这对于在决定阻塞接收器之前进行“乐观检查”非常有用。
recv_timeout尝试在此接收器上等待一个值如果相应的通道已挂断或达到最后期限则返回错误。如果没有可用的数据并且可能发送更多的数据此函数将始终阻止当前线程。将消息发送到相应的发件人或SyncSender后此收件人将唤醒并返回该消息。如果相应的Sender已断开连接或者在该呼叫被阻止时断开了连接则该呼叫将唤醒并返回Err以指示在此信道上无法再接收到消息。但是由于通道是缓冲的因此在断开连接之前发送的消息仍将被正确接收。
recv_deadline返回一个迭代器该迭代器将阻止等待消息但永远不要惊慌当频道挂断时它将返回None。
iter返回一个迭代器该迭代器将尝试生成所有挂起的值。如果没有更多挂起的值或通道已挂起它将返回None。迭代器永远不会死机或者通过等待值来阻止用户。 关于MPSC讲解
其中mpsc是Multi producer, Single consumer FIFO queue的缩写,即多生产者单消费者先入先出队列。Rust标准库提供的channel是MPSC多生产者单消费者模型这意味着可以有多个发送端Sender向同一个接收端Receiver发送消息。这种模式非常适用于工作队列模型其中多个生产者线程生成任务而单个消费者线程处理这些任务。
除了MPSC之外,还有如下几种模型:
SPSC(Single Producer Single Consumer): 单生产者单消费者。
SPMC(Single Producer Multiple Consumer): 单生产者多消费者。
MPSC(Multi Producer Single Consumer): 多生产者单消费者, Rust中标准的mpsc模型。
MPMC(Multi Producer Multi Consumer)*: 多生产者多消费者。