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

news2024/11/29 18:46:02

目录

前言

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等待线程执行结束。

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一定是有效的。

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.coloradmin.cn/o/2249925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用Java爬虫获取阿里巴巴中国站跨境属性的详细指南

在全球化贸易的浪潮中&#xff0c;跨境电商正成为连接全球买家和卖家的重要桥梁。阿里巴巴中国站作为全球领先的B2B电子商务平台&#xff0c;提供了海量的商品信息&#xff0c;其中跨境属性信息对于跨境电商尤为重要。本文将详细介绍如何使用Java编写爬虫&#xff0c;从阿里巴巴…

「Qt Widget中文示例指南」如何为窗口实现流程布局?(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文将展示如何为不…

鸿蒙学习使用模拟器运行应用(开发篇)

文章目录 1、系统类型和运行环境要求2、创建模拟器3、启动和关闭模拟器4、安装应用程序包和上传文件QA:在Windows电脑上启动模拟器&#xff0c;提示未开启Hyper-V 1、系统类型和运行环境要求 Windows 10 企业版、专业版或教育版及以上&#xff0c;且操作系统版本不低于10.0.18…

Java后端如何进行文件上传和下载 —— 本地版

简介&#xff1a; 本文详细介绍了在Java后端进行文件上传和下载的实现方法&#xff0c;包括文件上传保存到本地的完整流程、文件下载的代码实现&#xff0c;以及如何处理文件预览、下载大小限制和运行失败的问题&#xff0c;并提供了完整的代码示例。 大体思路 1、文件上传 …

SqlServer强制转换函数TRY_CONVERT和TRY_CAST

SqlServer强制转换函数TRY_CONVERT和TRY_CAST的介绍和案例分享 1、本节内容 CAST 和 CONVERT TRY_CAST TRY_CONVERT 适用于&#xff1a; SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse Analytics 分析平台系统 (PDW)Microsoft Fabric 中的 SQL 分析端点Micro…

透视投影(Perspective projection)与等距圆柱投影(Equirectangular projection)

一、透视投影 1.方法概述 Perspective projection&#xff08;透视投影&#xff09;是一种模拟人眼观察三维空间物体时的视觉效果的投影方法。它通过模拟观察者从一个特定视点观察三维场景的方式来创建二维图像。在透视投影中&#xff0c;远处的物体看起来比近处的物体小&…

linux 中后端jar包启动不起来怎么回事 -bash: java: 未找到命令

一、用以下命令检查jdk版本 输入&#xff1a;java -version&#xff0c;如果JDK 环境变量没有配置&#xff0c;你会看到如下提示 二、配置jdk环境 1.先找到/etc/profile文件&#xff0c;然后在该文件最后面加上以下配置 export JAVA_HOME/usr/local/jdk-21.0.1 export PATH$…

TDengine在debian安装

参考官网文档&#xff1a; 官网安装文档链接 从列表中下载获得 Deb 安装包&#xff1b; TDengine-server-3.3.4.3-Linux-x64.deb (61 M) 进入到安装包所在目录&#xff0c;执行如下的安装命令&#xff1a; sudo dpkg -i TDengine-server-<version>-Linux-x64.debNOTE 当…

Java开发工程师最新面试题库系列——Java基础部分(附答案)

如果你有更好的想法请在评论区留下您的答案&#xff0c;一起交流讨论# 面向对象有哪些特征&#xff1f; 答&#xff1a;继承、封装、多态 JDK与JRE的区别是什么&#xff1f; 答&#xff1a;JDK是java开发时所需环境&#xff0c;它包含了Java开发时需要用到的API&#xff0c;JRE…

linux系统下如何将xz及ISO\img等格式压缩包(系统)烧写到优盘(TF卡)

最近用树莓派做了个NAS&#xff0c;效果一般&#xff0c;缺少监控及UI等&#xff0c;详细见这篇文章&#xff1a; https://blog.csdn.net/bugsycrack/article/details/135344782?spm1001.2014.3001.5501 所以下载了专门的基于树莓派的NAS系统直接使用。这篇文章是顺便复习一…

计算机的错误计算(一百六十八)

摘要 算式“(5^25*(1/25)^(1/5)*3^25(1/25)^(1/5)*5^25*3^(251/5)-(9/25)^(1/5)*3^25*5^25-(1/25)^(1/5)*3^25*5.0^25*(13^(1/5)-3^(2/5.0)))”的值为0。但是&#xff0c;在 MATLAB 中计算它&#xff0c;则输出含有15位整数。 例1. 计算 直接贴图吧&#xff1a; 这样&#x…

Python学习------第十四天

匿名函数 1.函数作为参数来传递 &#xff08;函数的参数中调用另外一个函数&#xff09; #定义一个函数&#xff0c;接受另一个函数作为参数传入 #计算逻辑的传入 def test_func(compute):result compute(1,2)print(result)print(f"{type(result)}")print(f"…

【经典论文阅读】Transformer(多头注意力 编码器-解码器)

Transformer attention is all you need 摘要 完全舍弃循环 recurrence 和卷积 convolutions 只依赖于attention mechanisms 【1】Introduction 完全通过注意力机制&#xff0c;draw global dependencies between input and output 【2】Background 1&#xff1a;self-…

Java——多线程案例

目录 一、单例模式 1.饿汉模式 2.懒汉模式 3.线程安全问题 4.解决线程安全问题(懒汉模式) 二、阻塞式队列 1.什么是阻塞队列 2.生产者消费模型 生产者消费者模型意义&#xff1a; 1.解耦合 2.削峰填谷 3.标准库中的阻塞队列 三、定时器 1.定时器是什么 2.标准库中的…

AI 声音:数字音频、语音识别、TTS 简介与使用示例

在现代 AI 技术的推动下&#xff0c;声音处理领域取得了巨大进展。从语音识别&#xff08;ASR&#xff09;到文本转语音&#xff08;TTS&#xff09;&#xff0c;再到个性化声音克隆&#xff0c;这些技术已经深入到我们的日常生活中&#xff1a;语音助手、自动字幕生成、语音导…

Linux服务器安装mongodb

因为项目需要做评论功能&#xff0c;领导要求使用mongodb&#xff0c;所以趁机多学习一下。 在服务器我们使用docker安装mongodb 1、拉取mongodb镜像 docker pull mongo &#xff08;默认拉取最新的镜像&#xff09; 如果你想指定版本可以这样 docker pull mongo:4.4&#…

Java基础 设计模式——针对实习面试

目录 Java基础 设计模式单例模式工厂模式观察者模式策略模式装饰器模式其他设计模式 Java基础 设计模式 单例模式 单例模式&#xff08;Singleton Pattern&#xff09; 定义&#xff1a;确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问这个实例。适用场景&…

分布式搜索引擎之elasticsearch单机部署与测试

分布式搜索引擎之elasticsearch单机部署与测试 1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器&#xff0c;因此需要让es和kibana容器互联。这里先创建一个网络&#xff1a; docker network create es-net1.2.加载镜像 这里我们采用elasticsearch的7.12.1版本的…

【工具】JS解析XML并且转为json对象

【工具】JS解析XML并且转为json对象 <?xml version1.0 encodingGB2312?> <root><head><transcode>hhhhhhh</transcode></head><body><param>ccccccc</param><param>aaaaaaa</param><param>qqqq<…

CSDN设置成黑色背景(谷歌 Edge)

一.谷歌浏览器 浏览器地址输入&#xff1a;Chrome://flags搜索框输入&#xff1a;enable-force-dark将default 改成 enabled&#xff0c;点击重启浏览器 二.Edge浏览器 浏览器地址输入&#xff1a;edge://flags搜索里面输入Auto Dark Mode for Web Contents将default 改成 e…