【Rust】17. Rust 中的并发

news2024/11/18 16:40:45

在这里插入图片描述

17.1 线程

在这里插入图片描述

17.1.1 spawn:创建新线程

  • thread::spawn:创建一个新线程,需要传递一个闭包,并在其中包含希望在新线程运行的代码
  • thread::sleep:调用强制线程停止执行一小段时间。比如:thread::sleep(Duration::from_millis(1));

在这里插入图片描述

17.1.2 join:等待所有线程结束

  • thread::spawn 的返回值类型是 JoinHandleJoinHandle 是一个拥有所有权的值
  • JoinHandle.join:通过调用 handlejoin 会阻塞当前线程直到 handle 所代表的线程结束(也就是等待所关联的线程运行结束)
  • join 的调用位置会影响线程的运行顺序(比如:影响线程是否同时运行)

在这里插入图片描述
在这里插入图片描述

17.1.3 线程与 move 闭包

  • 可以在参数列表前使用 move 关键字强制闭包获取其使用的环境值的所有权。比如:使用 main 函数中的外部数据,这样就无法知道这些外部数据的生命周期,因此无法编译
  • move 关键字经常用于传递给 thread::spawn 的闭包,因为闭包会获取从环境中取得的值的所有权,因此会将这些值的所有权从一个线程传送到另一个线程
  • move 关键字覆盖了 Rust 默认保守的借用,但它不允许我们违反所有权规则

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

17.2 使用消息传递在线程间传送数据

17.2.1 消息传递(message passing)与信道(channel)

  • use std::sync::mpsc;mpsc多个生产者,单个消费者(multiple producer, single consumer)的缩写。简而言之,Rust 标准库实现信道的方式意味着一个信道可以有多个产生值的 发送(sending)端,但只能有一个消费这些值的 接收(receiving)端
  • mpsc::channel 函数返回一个元组:第一个元素是发送端(发送者,tx),而第二个元素是接收端(接收者,rx,具有迭代器特性)
  • 发送者方法send转移所有权
  • send转移所有权):用来获取需要放入信道的值;该方法返回一个 Result<T, E> 类型,所以如果接收端已经被丢弃了,将没有发送值的目标,所以发送操作会返回错误
  • 接收者方法recvtry_recv
  • recv:该方法会阻塞主线程执行直到从信道中接收一个值(即:一直等待消息,直到接收到一个值才会结束)。一旦发送了一个值,recv 会在一个 Result<T, E> 中返回它。当信道发送端关闭,recv 会返回一个错误表明不会再有新的值到来了
  • try_recv不会阻塞,相反它立刻返回一个 Result<T, E>:Ok 值包含可用的信息,而 Err 值代表此时没有任何消息。如果线程在等待消息过程中还有其他工作时使用 try_recv 很有用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

17.2.2 信道与所有权转移

  • send:函数获取其参数的所有权并移动这个值归接收者所有

在这里插入图片描述

17.2.3 发送多个值并观察接收者的等待

  • 接收者 rx 是一个迭代器

在这里插入图片描述

17.2.4 通过克隆发送者来创建多个生产者

  • 注意:下面的例子,是不确定顺序的实现!可以添加 join 来阻塞线程,进而控制接收消息的先后顺序

在这里插入图片描述
在这里插入图片描述

17.3 共享状态并发

在这里插入图片描述

17.3.1 互斥器一次只允许一个线程访问数据

  • 互斥器(mutex)在任意时刻只允许一个线程访问某些数据。为了访问互斥器中的数据,线程首先需要通过**获取互斥器的 锁(lock)**来表明其希望访问数据

在这里插入图片描述

17.3.2 互斥器 Mutex<T>

  • use std::sync::Mutex;
  • Mutex<T>:使用关联函数 new 来创建一个 Mutex<T>Mutex<T> 是一个智能指针;Mutex<T> 提供了内部可变性,就像 Cell 系列类型那样
  • lock获取锁,以访问互斥器中的数据,返回一个叫做 MutexGuard 的智能指针(这个智能指针实现了 Deref 来指向其内部数据;其也提供了一个 Drop 实现当 MutexGuard 离开作用域时自动释放锁)。这个调用会阻塞当前线程,直到我们拥有锁为止
  • 锁的特性,如下所示
  • 如果另一个线程拥有锁,并且那个线程 panic 了,则 lock 调用会失败。在这种情况下,没人能够再获取锁(所以这里可以选择 unwrap 并在遇到这种情况时使线程 panic
  • 一旦获取了锁,就可以将返回值视为一个其内部数据的可变引用了(在示例中,m 的类型是 Mutex<i32> 而不是 i32,所以必须获取锁才能使用这个 i32 值)

在这里插入图片描述

17.3.3 在线程间共享 Mutex<T>(一):不能将锁的所有权移动到多个线程中

在这里插入图片描述

17.3.4 在线程间共享 Mutex<T>(二):多线程和多所有权

  • Rc<T> 并不能安全的在线程间共享
    在这里插入图片描述
    在这里插入图片描述

17.3.5 在线程间共享 Mutex<T>(三):原子引用计数 Arc<T>

  • Arc<T>:原子引用计数(atomically reference counted)类型,一个类似 Rc<T> 并可以安全的用于并发环境的类型Arc<T>Rc<T> 有着相同的 API
  • Mutex<T> 提供了内部可变性,就像 Cell 系列类型那样,因此如同使用 RefCell<T> 可以改变 Rc<T> 中的内容那样,同样的可以使用 Mutex<T> 来改变 Arc<T> 中的内容

在这里插入图片描述

17.3.6 RefCell<T>/Rc<T> 与 Mutex<T>/Arc<T> 的相似性

在这里插入图片描述

17.4 使用 Sync 和 Send trait 的可扩展并发

17.4.1 通过 Send 允许在线程间转移所有权

  • Send trait(所有权):一个实现了 Send 的类型值的所有权可以在线程间传送
  • Send 的类型:几乎所有的 Rust(基本)类型都是 Send 的、完全由 Send 的类型组成的类型也会自动被标记为 SendArc<T>
  • Send 的类型::Rc<T>、裸指针(raw pointer)

在这里插入图片描述

17.4.2 Sync 允许多线程访问

  • Sync trait(引用):一个实现了 Sync 的类型可以安全的在多个线程中拥有其值的引用
  • Sync 的类型:基本类型是 Sync 的、完全由 Sync 的类型组成的类型也是 Sync 的、Mutex<T>
  • Sync 的类型:Rc<T>RefCell<T>Cell<T>

在这里插入图片描述

17.4.3 手动实现 Send 和 Sync 是不安全的

  • 注意:通常并不需要手动实现 SendSync trait!

在这里插入图片描述

17.5 小结

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/191982.html

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

相关文章

深入理解MySql(一)MySql视图、存储过程、预处理语句、触发器、定时器

MySql视图、存储过程、预处理语句、触发器、定时器 1、视图 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 视图只保存了查询的…

iOS面试- 0x02 WebView

有了UIWebView&#xff0c;为什么还需要WKWebView&#xff1f; UIWebVieW的缺点&#xff1a; 笨重难用、内存泄露、内存消耗大&#xff0c;性能差 —— WKWebView提高性能 WKWebView 拥有60fps滚动刷新率和safari相同的js引擎等优势。 1、WKWebView 白屏问题 WKWebView是一个多…

ElasticSearch6.x版本的Scroll滚动查询讲解及Kibana和SpringBoot实操演示

文章目录一、Scroll滚动查询介绍二、Kibana上操作三、SpringBoot中操作四、总结一、Scroll滚动查询介绍 ElasticSearch中在进行普通的查询时&#xff0c;默认只会查询出来10条数据。我们通过设置ElasticSearch中的size可以将最终的查询结果从10增加到10000。但这时候如果我们需…

Sensor曝光和帧率基础知识

Sensor曝光和帧率基础知识1. 简介2. H_BLANK和V_BLANK3. 曝光原理3.1 Sensor逐行曝光基本原理3.2 Sensor全局曝光基本原理4. 曝光时间计算公式4.1 曝光一行的时间line_timeline\_timeline_time4.2 曝光一帧的时间exposure_timeexposure\_timeexposure_time4.3 帧率(fps)的计算1…

2023,“蔚小理”真的经不起更多“事故”了

历史总是惊人的相似。2013年&#xff0c;哈弗品牌独立出来&#xff0c;与长城品牌并行运营&#xff0c;当时推出两年的哈弗H6正卖得火热&#xff0c;推动SUV这个细分品类在中国快速成长&#xff0c;中国自主品牌也借SUV开始攻占被合资品牌占领的市场。时移势易。十年后的2023年…

浅析TSINGSEE车载监控平台助力城市公交智能监管的方案设计

道路运输已成为铁路以外最重要的地面运输方式&#xff0c;在国民经济和社会发展中发挥着举足轻重的作用。然而&#xff0c;随着汽车的普及和交通需求的快速增长&#xff0c;道路运输带来的交通拥堵、交通事故和环境污染等负面影响日益突出&#xff0c;逐渐成为全球经济社会发展…

Baklib支招 ——如何帮助企业创建内部维基(wiki)?

企业维基&#xff08;wiki&#xff09;的重要的好处就是&#xff1a;可以按照个性化的理解和需求进行编辑&#xff0c;而不担心被别人修改。这个个人维基可以作为自己的外挂大脑使用&#xff0c;但是不要成为一个垃圾筐&#xff0c;什么都往里装&#xff0c;扔进去就再也不看了…

计算机SCI论文重复率需要控制在多少? - 易智编译EaseEditing

SCI论文的重复率一般在20%左右&#xff0c;一般是没有没问题的。 SCI期刊在检查论文重复率时&#xff0c;并不是简单的只看总重复率&#xff0c;还有单篇重复率。 目前有很多SCI期刊都会先查重&#xff0c;看重复率&#xff0c;但也会看内容。 而且&#xff0c;重复率高也不一定…

lio-sam学习笔记(一)

前言&#xff1a; 对于lio-sam框架的安装配置。 每一回不同框架的配置真是要了老命了。。。 一、安装依赖 官方github&#xff1a; GitHub - TixiaoShan/LIO-SAM: LIO-SAM: Tightly-coupled Lidar Inertial Odometry via Smoothing and Mapping lio-sam主要有两个依赖&am…

6.深度学习和计算

6.深度学习和计算 目录 层和块 自定义块顺序块在前向传播函数中执行代码 参数管理 参数访问 目标参数一次性访问所有参数从嵌套块收集参数 参数初始化 内置初始化自定义初始化 参数绑定 自定义层 不带参数的层带参数的层 读写文件 加载和保存张量加载和保存模型参数使用GPU 计…

JS中函数声明与函数表达式的区别

1、函数定义 JavaScript 中定义函数最常用的方式是函数声明和函数表达式。这两种技术非常相似&#xff0c;有时甚至难以区分&#xff0c;它们之间还是存在着微妙的差别。 JavaScript 定义函数的最基本方式是函数声明&#xff1a; 函数声明必须独立&#xff0c;但也能够被包含在…

REST开发

REST风格一、简介优点REST风格二、使用三、注解PathVariableResponseBody、RequestParam和PathVariable区别应用快速开发一、简介 REST&#xff08;Representational State Transfer&#xff09;&#xff0c;表现形式状态转换 传统风格资源描述形式 http://localhost/user/ge…

Smartbi电子表格软件集成的优势

Smartbi电子表格软件作为国内顶尖的企业报表工具&#xff0c;具有“真Excel”特色&#xff0c;直接用Excel作为设计器&#xff0c;仅需安装一个插件就可以解决众多报表难题。无需增加学习成本&#xff0c;学习一个新的设计器&#xff0c;更能解决Excel的取数、性能等问题&#…

Wireless M-Bus介绍-摘自OMS

Wireless M-Bus(wM-Bus或无线M-Bus)是成熟的Wired M-Bus(有线M-Bus)标准的后续增强。2003年&#xff08;这里估计是资料错误,第一个无线M-Bus的标准是2013年的&#xff09;&#xff0c;EN 13757-4首次对其进行了描述&#xff08;&#xff1f;&#xff09;。该标准为M-Bus层模型…

Python 全栈系列216 APIFunc.Database启动流程

说明 上次做了一些改进,现在关注使用的流程。 内容 1 基础概念 能大约知道大致的几个部分有助于记忆操作步骤,以后这个项目的代号就是ABD了。 1 所有启动相关的代码全部封装在镜像apifunc_database_model1:v3,基于这个镜像就可以启动一个所有对应的服务流2 在Portal上有相关…

为WEB3 的GameFi行业爆发提供全新动力

WEB3 GameFi的突破口在2022年末Octopus Network Co-founder Louis指出&#xff0c;GameFi要完成2023年的全新爆发需要将所有权与经营权分离&#xff0c;所有用户共同参与由平台成长带来的市场红利&#xff0c;单一的Gamefi将会更加产品化&#xff0c;体验化&#xff0c;具备整合…

详解树状数组

前言树状数组或二叉索引树&#xff08;Binary Indexed Tree&#xff09;&#xff0c;又以其发明者命名为 Fenwick 树。其初衷是解决数据压缩里的累积频率的计算问题&#xff0c;现多用于高效计算数列的前缀和、区间和。它可以以 O(logn) 的时间得到任意前缀和。并同时支持在 O(…

JVM线上问题定位命令

概述 本文主要介绍下平常可能会使用到的命令&#xff1a;jps、jinfo、jmap、jstat、jstack jps jps主要是查看Java进程号&#xff0c;有个Java进程号后面的命令也才能发挥作用。 jps -help可以列出jps支持的参数&#xff0c;大家可以试一下 jinfo jinfo后面跟jps打出来的…

nvm(node版本管理)

文章目录1 安装2 配置镜像&#xff0c;提高下载速度3 常用命令4 vue版本与node版本的依赖关系注意事项1 nvm use 报错1 安装 官方下载地址&#xff1a; https://nvm.uihtm.com/ 官网同时还给出了非常详细的指令文档。 下载windows版本的安装包&#xff0c;按照提示点击下一步…

网络通信Socket学习记录

网络通信Socket Socket socket起源于unix&#xff0c;而unix/linux基本思想就是一切皆文件&#xff0c;也称为文件描述符socket是对“open—write/read—close”的一种实现socket是对TCP/IP协议的一种封装&#xff0c;socket本身不是协议&#xff0c;通过socket才能使用TCP/I…