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

devtools/2024/11/30 8:24:17/

目录

前言

Fork和Join


前言

本节会介绍Rust中的并发编程,并发编程在编程中是提升cpu使用率的一大利器,通过多线程技术提升效率,Rust的并发和其他编程语言的并发不同的地方在于,Rust号称无畏并发。更重要的一点是安全。Rust中所有权机制依然存在于多线程当中。

本节会介绍Rust中并发编程的三种方式

1.Fork和Join

2.通道

3.共享可变状态

我们一个一个来看

Fork和Join

Fork和Join在编程语言中是一种比较常见的并发模式,Fork的意思就是新开线程,Join的意思就是等待线程的结果,这是非常通用的做法,只要任务可以切分,使用Fork和Join的方式往往都会取得比较好的结果。

我们以一个简单的例子来说明,将一个String类型的vector中的元素分别计算字符串的长度,如果串型来做,就for循环vec,分别计算元素的长度,我们使用Fork和Join来实现一下。

下面的代码中,定义了5个元素的vec,在计算前还定义了一个JoinHandle的vec,然后我们循环data,使用的into_iter()表示将元素的所有权转移给迭代器,在for循环内部,使用thread::spawn启动线程,线程执行的任务使用闭包表示,比较特殊的是在闭包的开头,新增了move关键字,这是为了将所有权转移到闭包内,在这里就是循环中的变量ss,最后一个for循环,使用join等待线程执行结束。

rust">use std::collections::HashSet;
use std::sync::Arc;
use std::thread;
use std::thread::JoinHandle;fn main() {let data: Vec<String> = vec![String::from("hello"),String::from("rust"),String::from("flink"),String::from("kafka"),String::from("hadoop"),];let mut thread_handles: Vec<JoinHandle<()>> = vec![];for ss in data.into_iter() {thread_handles.push(thread::spawn(move || {println!("{} length = {}", ss, ss.len());}));}for handle in thread_handles {handle.join().unwrap();}
}

在上面的基础上,我们加上一个小需求来感受一下,Rust的并发安全问题,我们定义一个黑词vec,当处理的词语出现在黑词中时,做特殊输出。如果是别的编程语言,非常简单,只需要让线程读取一个HashSet即可,因为只读,但是在Rust中不行,为什么呢?假设存在这样的一个HashSet,存储黑词,在主线程中定义,那么当所有者离开作用域后,HashSet会被清理,此时如果子线程依然还在读这个HashSet,就会造成问题。那么在Rust中如何解决呢?在Rust中,智能指针Arc允许一个值存在多个所有者,是一个特殊情况,当最后一个所有者离开作用域后,这块内存才会被回收。

下面代码实现了上面的功能,使用了Arc共享了所有者。下面的代码中,我们定义HashSet,并且使用Arc使这个HashSet变成可以共享所有者。并在在每个线程中都有一个变量是所有者,保证了线程读到的HashSet一定是有效的。

rust">use std::collections::HashSet;
use std::sync::Arc;
use std::thread;
use std::thread::JoinHandle;fn main() {let data: Vec<String> = vec![String::from("hello"),String::from("rust"),String::from("flink"),String::from("kafka"),String::from("hadoop"),];let mut black_words: HashSet<String> = HashSet::new();black_words.insert(String::from("kafka"));let black_words_arc: Arc<HashSet<String>> = Arc::new(black_words);let mut thread_handles: Vec<JoinHandle<()>> = vec![];for ss in data.into_iter() {let black_word_temp_arc = Arc::clone(&black_words_arc);thread_handles.push(thread::spawn(move || {if !black_word_temp_arc.contains(&ss) {println!("{} length = {}", ss, ss.len());} else {println!("black_word")}}));}for handle in thread_handles {handle.join().unwrap();}
}


http://www.ppmy.cn/devtools/138138.html

相关文章

# issue 6 网络编程基础

一、网络的物理结构和光纤千兆网络 首先&#xff0c;我们需要知道网络的物理结构——数据是如何从一台机器传输到另外一台机器的 这个过程是非常重要的。现在很多人做软件开发&#xff0c;只会软件角度&#xff0c;这导致讲软件原理头头是道&#xff0c;但是连数据线都不会接&a…

基于OpenCV视觉库让机械手根据视觉判断物体有无和分类抓取的例程

项目实例&#xff0c;在一个无人封闭的隔绝场景中&#xff0c;根据视觉判断物件的有无&#xff0c;通过机械手 进行物件分类提取&#xff0c;并且返回状态结果&#xff1b; 实际的场景是有一个类似采血的固件支架盘&#xff0c;上面很多采血管&#xff0c;采血管帽颜色可能不同…

深入探索Flax:一个用于构建神经网络的灵活和高效库

深入探索Flax&#xff1a;一个用于构建神经网络的灵活和高效库 在深度学习领域&#xff0c;TensorFlow 和 PyTorch 作为主流的框架&#xff0c;已被广泛使用。不过&#xff0c;Flax 作为一个较新的库&#xff0c;近年来得到了越来越多的关注。Flax 是一个由Google Research团队…

租赁小程序|租赁系统搭建|租赁系统需求

随着信息技术的高速发展&#xff0c;租赁行业逐渐向智能化、便捷化方向迈进。一款优秀的租赁小程序&#xff0c;旨在为用户提供一站式的租赁服务体验&#xff0c;同时帮助租赁企业优化管理流程&#xff0c;提高业务效率。 一、用户需求精准把握 在开发任何软件产品时&#xff0…

2024年11月28日Github流行趋势

项目名称&#xff1a;OpenInterpreter 项目维护者&#xff1a;KillianLucas, Notnaton, MikeBirdTech, CyanideByte, ericrallen项目介绍&#xff1a;一个自然语言计算机接口&#xff0c;允许用户通过自然语言与计算机交互。项目star数&#xff1a;56,695项目fork数&#xff1a…

TypeScript 命名空间与模块

在 TypeScript 中&#xff0c;命名空间和模块是两种不同的代码组织方式&#xff0c;它们都旨在帮助你管理和维护大型代码库。命名空间提供了一种将相关功能组织在一起的方式&#xff0c;而模块则允许你将代码分解成可重用的单元。在本文中&#xff0c;我们将探讨命名空间和模块…

2024年11月29日Github流行趋势

项目名称&#xff1a;aisuite 项目维护者&#xff1a;ksolo, standsleeping, rohitprasad15, jeffxtang, andrewyng项目介绍&#xff1a;为多个生成式AI供应商提供简单、统一的接口。项目star数&#xff1a;4,302项目fork数&#xff1a;368 项目名称&#xff1a;screenshot-to…

评分规则的建模,用户全选就是满分10分(分数可自定义), 选2个5分, 选2个以下0分

子夜(603***854) 15:11:40 和各位讨论一下设计问题: 有个有业务场景: 有一组产品共4个产品(数目用户可自定义), 需要一套规则,比如如果用户全选就是满分10分(分数可自定义), 选2个5分, 选2个以下0分 又比如另一组产品 产品有个必选属性,如果选了其中所有的必选则5分, 其他项每1…