【第十一课】Rust并发编程(二)

news/2024/11/29 21:17:55/

目录

前言

Channel

多生产者


前言

在上一节中,我们介绍了Rust中并发编程的方式之一:Fork和Join,通过新建线程提升代码的效率,这节课我们介绍并发编程的第二种方式:通道。Channel就类似于水管,通过Channel可以连接多个线程,达到多个线程之间协调作业。

Channel

我们以一个简单的需求为例来解释下Channel的使用方法。完成WordCount,使用2个线程,线程1从文件中读取数据,将数据通过Channel发送给线程2,线程2负责计算wordcount。

注意:

(1)下面代码中文件路径使用的是绝对路径

(2)使用mpsc::channel()可以创建一个通道,下面代码还指定了泛型,即在下面的代码中通道中只可以发送String类型的数据

(3)通道的返回值是一个发送者,一个消费者,发送者给线程1中的闭包,因为线程1负责读数据发送到通道中,消费者给线程2中的闭包,线程2负责读取数据处理wordcount。

(4)mpsc:指的是多生产者,单消费者的意思,即multi-producer,single-consumer。

rust">use std::collections::HashMap;
use std::sync::mpsc;
use std::thread::JoinHandle;
use std::{fs, io, thread};fn main() {let paths = vec!["/Users/xxxxx/rustproject/lesson11/src/test.txt".to_string()];let (receiver, handler1) = start_file_reader_thread(paths);let handler2 = start_file_word_count_thread(receiver);let _ = handler1.join().unwrap();let _ = handler2.join().unwrap();
}// 读取文件内容
fn start_file_reader_thread(documents: Vec<String>,
) -> (mpsc::Receiver<String>, JoinHandle<Result<(), io::Error>>) {let (sender, receiver) = mpsc::channel::<String>();let handle = thread::spawn(move || -> Result<(), io::Error> {for filename in documents {let text = fs::read_to_string(filename)?;if sender.send(text).is_err() {break;}}Ok(())});(receiver, handle)
}// word count
fn start_file_word_count_thread(texts: mpsc::Receiver<String>) -> JoinHandle<()> {let handle = thread::spawn(move || {// 处理let mut wc: HashMap<String, u32> = HashMap::new();for line in texts {let words: Vec<String> = line.split(" ").map(|x| x.to_string()).collect();for word in words {match wc.get(&word) {None => {wc.insert(word, 1);}Some(old) => {wc.insert(word, old + 1);}}}}// 打印for (word, cnt) in wc {println!("key = {}, count = {}", word, cnt);}});handle
}

多生产者

上面是单生产者的例子,我们扩展一下,使用多生产者。

注意:
(1)使用生产者的clone方法,扩展出多个生产者传递给不同的线程发送消息。

rust">use std::collections::HashMap;
use std::sync::mpsc;
use std::{fs, io, thread};fn main() {let path1 = vec!["/Users/xxx/rustproject/lesson11/src/test1.txt".to_string()];let path2 = vec!["/Users/xxx/rustproject/lesson11/src/test2.txt".to_string()];let (producer, consumer) = mpsc::channel::<String>();let producer1 = producer.clone();// 生产者let handler1 = thread::spawn(move || -> Result<(), io::Error> {for filename in path1 {let text = fs::read_to_string(filename)?;if producer.send(text).is_err() {break;}}Ok(())});let handler2 = thread::spawn(move || -> Result<(), io::Error>{for filename in path2 {let text = fs::read_to_string(filename)?;if producer1.send(text).is_err() {break;}}Ok(())});// 消费者let handler3 = thread::spawn(move || {// 处理let mut wc: HashMap<String, u32> = HashMap::new();for line in consumer {let words: Vec<String> = line.split(" ").map(|x| x.to_string()).collect();for word in words {match wc.get(&word) {None => {wc.insert(word, 1);}Some(old) => {wc.insert(word, old + 1);}}}}// 打印for (word, cnt) in wc {println!("key = {}, count = {}", word, cnt);}});//handler1.join();handler2.join();handler3.join();
}


http://www.ppmy.cn/news/1550990.html

相关文章

Vue小项目(开发一个购物车)

基于Vue知识点1&#xff08;点击跳转&#xff09;、Vue知识点2&#xff08;点击跳转&#xff09; ​想要学习更多前端知识&#xff1a;点击Web前端专栏 接下来我们开发一个如下图所示&#xff0c;有最基本购物车功能的简易小项目 下面这是最基本的HTMLCSS框架&#xff01;&…

【R安装】VSCODE安装及R语言环境配置

目录 VSCODE下载及安装VSCODE上配置R语言环境参考 Visual Studio Code&#xff08;简称“VSCode” &#xff09;是Microsoft在2015年4月30日Build开发者大会上正式宣布一个运行于 Mac OS X、Windows和 Linux 之上的&#xff0c;针对于编写现代Web和云应用的跨平台源代码编辑器&…

YOLOv8-Pose NCNN安卓部署

YOLOv8-Pose NCNN安卓部署 前言 YOLOv8-Pose NCNN安卓部署 目前的帧率可以稳定在30帧左右&#xff0c;下面是这个项目的github地址&#xff1a;https://github.com/gaoxumustwin/ncnn-android-yolov8-pose 介绍 在做YOLOv8-Pose NCNN安卓部署的时候&#xff0c;在github上…

2024年11月27日Github流行趋势

项目名称&#xff1a;screenshot-to-code 项目维护者&#xff1a;abi clean99 sweep-ai kachbit vagusX项目介绍&#xff1a;通过上传截图将其转换为整洁的代码&#xff08;支持HTML/Tailwind/React/Vue&#xff09;。项目star数&#xff1a;62,429项目fork数&#xff1a;7,614…

QT 实现窗口关闭动画

1.实现效果 两种关闭窗口动画效果。 下坠式关闭动画。 中心式关闭动画 2.实现思路 创建了两个动画并行执行,一个是控制窗口尺寸的动画,一个是控制透明度的动画。 先创建一个closeAnimation动画,然后创建opacityAnimation动画,创建一个QParallelAnimationGroup并行动画…

Table 滚动条始终停靠在可视区域的底部

1. 话题引入 存在这样一个场景&#xff1a;当页面尺寸发生变化时&#xff0c;希望滚动条能够随之动态调整&#xff0c;始终展示在 table 的可视区域的最下方&#xff0c;而不是整个 table 本身的最底部。 这种行为可以提升用户的使用体验&#xff0c;尤其是在处理大数据表格时…

裸金属服务器和专属主机的区别是什么?

在当今互联网时代&#xff0c;人们越来越重视服务器的使用。裸金属服务器和专属主机是两种常见的服务器形式。裸金属服务器和云主机有什么区别呢&#xff1f; 一、定义和概念 裸金属服务器和云主机都是租用物理服务器的一种方式。 裸金属服务器是指没有安装虚拟化技术的物理…

使用 Python 剪辑视频的播放速度

要使用 Python 调整视频的播放速度&#xff0c;可以利用 moviepy 库中的 fx&#xff08;特效&#xff09;模块来实现这一功能。通过 moviepy.editor 中的 VideoFileClip 类和 fx.speedx 函数&#xff0c;可以轻松地调整视频的播放速度。 安装 moviepy 首先&#xff0c;确保已…