当前位置: 首页 > wzjs >正文

网站结构形式有哪些天津建设工程信息网咨询电话

网站结构形式有哪些,天津建设工程信息网咨询电话,网络推广有几种方法,网站 图标 素材Rust 学习笔记&#xff1a;共享状态并发 Rust 学习笔记&#xff1a;共享状态并发互斥锁Mutex<T\> 的 API在多个线程之间共享互斥锁多线程的多重所有权Arc<T\>&#xff1a;原子引用计数类型 RefCell<T\>/Rc<T\> 与 Mutex<T\>/Arc<T\> 的相似…

Rust 学习笔记:共享状态并发

  • Rust 学习笔记:共享状态并发
    • 互斥锁
      • Mutex<T\> 的 API
      • 在多个线程之间共享互斥锁
      • 多线程的多重所有权
      • Arc<T\>:原子引用计数类型
    • RefCell<T\>/Rc<T\> 与 Mutex<T\>/Arc<T\> 的相似性

Rust 学习笔记:共享状态并发

消息传递是处理并发性的好方法,但不是唯一的方法。另一种方法是让多个线程访问相同的共享数据。

智能指针使多重所有权成为可能,多重所有权会增加复杂性,因为这些不同的所有者需要管理。Rust 的类型系统和所有权规则极大地帮助了这种管理的正确性。

让我们看看互斥锁,这是共享内存中比较常见的并发原语之一。

互斥锁

互斥只允许一个线程在任何给定的时间访问某些数据。要访问互斥锁中的数据,线程必须首先通过请求获取互斥锁来发出访问信号。lock 是一种数据结构,是互斥锁的一部分,它跟踪当前谁对数据具有独占访问权。

使用互斥锁的两条规则:

  1. 在使用数据之前,必须尝试获取锁。
  2. 在处理完互斥锁保护的数据后,必须解锁数据,以便其他线程可以获取该锁。

Mutex<T> 的 API

使用 new 函数创建 Mutex<T>。

为了访问互斥体内的数据,我们使用 lock 方法来获取锁。这个调用将阻塞当前线程,因此它不能做任何工作,直到轮到我们获得锁。

如果持有锁的另一个线程 panic,lock 方法将失败。在这种情况下,没有人能够获得锁,所以我们选择了 unwrap,并在这种情况下让线程 panic。

use std::sync::Mutex;fn main() {let m = Mutex::new(5);{let mut num = m.lock().unwrap();*num = 6;}println!("m = {m:?}");
}

在获得锁之后,可以将返回值(在本例中名为 num)作为对内部数据的可变引用。类型系统确保我们在使用 m 中的值之前获得锁。m 的类型是Mutex<i32>,而不是 i32,所以我们必须调用 lock 才能使用 i32 的值。

lock 方法返回一个名为 MutexGuard 的智能指针,封装在调用 unwrap 时处理的 LockResult 中。MutexGuard 智能指针实现了 Deref 和 Drop trait。

当 MutexGuard 超出作用域时自动释放锁,这种情况发生在内部作用域的末尾。因此,我们不会冒忘记释放锁而阻塞互斥锁被其他线程使用的风险,因为锁的释放是自动发生的。

在解除锁之后,我们可以打印互斥锁的值,并看到我们能够将内部的 i32 更改为 6。

在这里插入图片描述

在多个线程之间共享互斥锁

现在让我们尝试使用 Mutex<T> 在多个线程之间共享一个值。

启动 10 个线程,并让每个线程将计数器的值增加 1。

use std::sync::Mutex;
use std::thread;fn main() {let counter = Mutex::new(0);let mut handles = vec![];for _ in 0..10 {let handle = thread::spawn(move || {let mut num = counter.lock().unwrap();*num += 1;});handles.push(handle);}for handle in handles {handle.join().unwrap();}println!("Result: {}", *counter.lock().unwrap());
}

编译出错:

在这里插入图片描述

错误消息指出计数器值在循环的前一次迭代中被移动。Rust 告诉我们不能将互斥锁的所有权转移到多个线程中。让我们用多重所有权方法来修复错误。

多线程的多重所有权

我们知道使用智能指针 Rc<T> 可以将一个值赋给多个所有者。

修改之前的代码,用 Rc<T> 包装 Mutex<T>,并在将所有权转移到线程之前克隆 Rc<T>。

use std::rc::Rc;
use std::sync::Mutex;
use std::thread;fn main() {let counter = Rc::new(Mutex::new(0));let mut handles = vec![];for _ in 0..10 {let counter = Rc::clone(&counter);let handle = thread::spawn(move || {let mut num = counter.lock().unwrap();*num += 1;});handles.push(handle);}for handle in handles {handle.join().unwrap();}println!("Result: {}", *counter.lock().unwrap());
}

还是编译错误:

在这里插入图片描述

Rc<T> 不是线程安全的。当 Rc<T> 管理引用计数时,它将每次克隆调用的计数相加,并在每个克隆被删除时从计数中减去。但是它没有使用任何并发原语来确保计数的更改不会被另一个线程中断。这可能会导致错误的计数,进而导致内存泄漏或在我们完成之前丢弃值。

我们需要的是一种完全类似于 Rc<T> 的类型,但它以线程安全的方式对引用计数进行更改。

Arc<T>:原子引用计数类型

原子引用计数类型 Arc<T> 是一种类似 Rc<T> 的类型,在并发情况下使用是安全的。

原子是一种额外的并发原语,确保线程安全,但线程安全带来了性能损失。

Arc<T> 和 Rc<T> 具有相同的 API,因此我们通过更改 use 行、对 new 的调用和对 clone 的调用来修复程序。

use std::sync::{Arc, Mutex};
use std::thread;fn main() {let counter = Arc::new(Mutex::new(0));let mut handles = vec![];for _ in 0..10 {let counter = Arc::clone(&counter);let handle = thread::spawn(move || {let mut num = counter.lock().unwrap();*num += 1;});handles.push(handle);}for handle in handles {handle.join().unwrap();}println!("Result: {}", *counter.lock().unwrap());
}

程序运行成功,并输出了正确的结果:

在这里插入图片描述

注意,如果要进行简单的数值操作,标准库的 std::sync::atomic 模块提供了比 Mutex<T> 更简单的类型。这些类型提供对基本类型的安全、并发的原子访问。

在本例中,我们选择将 Mutex<T> 与基本类型一起使用,这样我们就可以专注于 Mutex<T> 是如何工作的。

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

你可能已经注意到 Mutex<T> 提供了内部可变性。

就像我们使用 RefCell<T> 来改变 Rc<T> 中的内容一样,我们使用 Mutex<T> 来改变 Arc<T> 中的内容。

使用 Rc<T> 有创建引用循环的风险,其中两个 Rc<T> 值相互引用,导致内存泄漏。类似地,Mutex<T> 也有创建死锁的风险。当一个操作需要锁定两个资源,并且两个线程各自获得了其中一个锁,导致它们永远等待对方时,就会发生这种情况。


文章转载自:

http://vb7BICEv.rysmn.cn
http://MiYKzPfn.rysmn.cn
http://xr370IuA.rysmn.cn
http://AXQMvt8f.rysmn.cn
http://gadjinKD.rysmn.cn
http://PsbFk0ME.rysmn.cn
http://bNnm0gsX.rysmn.cn
http://tIgTLNrq.rysmn.cn
http://Y6ngr86s.rysmn.cn
http://mZwFaolN.rysmn.cn
http://Xj9CQO3v.rysmn.cn
http://VAhM1tYt.rysmn.cn
http://TVA1zBjX.rysmn.cn
http://s9FqAiqn.rysmn.cn
http://w0y9TXjT.rysmn.cn
http://iyBkaVbu.rysmn.cn
http://0O0ep22V.rysmn.cn
http://10RaHkOa.rysmn.cn
http://AT9k43Mp.rysmn.cn
http://jRtdbtPP.rysmn.cn
http://vg0i0Ne8.rysmn.cn
http://LhXYPhQR.rysmn.cn
http://Cv3ktT7V.rysmn.cn
http://HQZ9iPKO.rysmn.cn
http://ceYnqsE1.rysmn.cn
http://2LXhLJaw.rysmn.cn
http://kuXtaNtY.rysmn.cn
http://gOObmn2T.rysmn.cn
http://Sx37CTzp.rysmn.cn
http://JeollSL7.rysmn.cn
http://www.dtcms.com/wzjs/648528.html

相关文章:

  • 黄岛因特网站建设公司打开网站 磁盘空间不足
  • 网站设计文字超链接外贸流程知识
  • 本地化网站建设移动互联和网站开发
  • php网站后台密码怎么修改快速建站教程网
  • 搭建论坛网站wordpress调用分类别名
  • 株洲网站制作公司在哪里电子工程专辑网站
  • 思源黑体做网站南通市港闸区城乡建设局网站
  • 网站制作的内容包含营销网站的功能
  • 怎样在百度建立自己的网站北京seo计费
  • php网站开发平台杭州规划建设网站
  • 中文企业网站模板wordpress+字体修改字体大小
  • 佛山快速建站哪家服务专业上海网站定制费用
  • 短视频营销的案例南京网站流量优化
  • 网站建设设计猫和老鼠做一个企业的官网可以做静态网站
  • wordpress 建站公司建设一个和聚享游差不多的网站
  • 找人帮你做ppt的网站吗国家开发大学网站作业怎么做
  • 长沙公司网站设计报价商城网站建设分为几块
  • 河南建设厅二建公示网站首页58同城类型网站制作
  • 棋牌类网站设计建设如何申请网页域名
  • 深圳网站建设公司官网购物网站上分期怎么做的
  • asp.net网站开发上海网站建设品牌
  • 怎样在手机上建设网站wordpress点击创建配置文件没反应
  • 客户网站建设洽谈方案福建省建设资格管理中心网站
  • 网站 相对路径云服务器建立多个网站
  • 网站怎么做才被收录快成都住建局官网从哪里查房屋备案没有
  • it公论 是建立在什么网站网站开发示例
  • 如何在百度上建网站安徽网站建设网站运营
  • 企业网站建设飞沐局网站建设合同
  • 站长工具seo综合查询pc网站制作的评价指标
  • 建站管理域名管理绑定外部域名中html5博客网站模板