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

太原网站建设外包须知传媒代写文案的软件

太原网站建设外包须知传媒,代写文案的软件,wex5 后端实现全网站开发,网站被劫持Rc与Arc实现1vN所有权机制 观察引用计数的变化一个例子多线程无力的Rc< T >Arc Rust所有权机制要求一个值只能有一个所有者&#xff0c;在大多数情况下&#xff0c;都没有问题&#xff0c;但是考虑以下情况&#xff1a; 在图数据结构中&#xff0c;多个边可能会拥有同一个…

Rc与Arc实现1vN所有权机制

    • 观察引用计数的变化
    • 一个例子
    • 多线程无力的Rc< T >
    • Arc

Rust所有权机制要求一个值只能有一个所有者,在大多数情况下,都没有问题,但是考虑以下情况:

  • 在图数据结构中,多个边可能会拥有同一个节点,该节点直到没有边指向它时,才应该被释放清理
  • 在多线程中,多个线程可能会持有同一个数据,但是你受限于 Rust 的安全机制,无法同时获取该数据的可变引用

为了解决这种问题,Rust通过引用计数的方式,允许一个数据资源在同一时刻拥有多个所有者。这种实现机制就是Rc和Arc,前者适用于单线程,后者适用于多线程。二者大部分情况下都相同。

fn main() {let s = String::from("hello, world");// s在这里被转移给alet a = Box::new(s);// 报错!此处继续尝试将 s 转移给 blet b = Box::new(s);
}

采用Rc就能解决

use std::rc::Rc;
fn main() {let a = Rc::new(String::from("hello, world"));let b = Rc::clone(&a);assert_eq!(2, Rc::strong_count(&a));assert_eq!(Rc::strong_count(&a), Rc::strong_count(&b))
}

使用 Rc::new 创建了一个新的 Rc< String > 智能指针并赋给变量 a,该指针指向底层的字符串数据。智能指针 Rc< T > 在创建时,还会将引用计数加 1,此时获取引用计数的关联函数 Rc::strong_count 返回的值将是 1。

接着,我们又使用 Rc::clone 克隆了一份智能指针 Rc< String >,并将该智能指针的引用计数增加到 2。由于 a 和 b 是同一个智能指针的两个副本,因此通过它们两个获取引用计数的结果都是 2。这里的clone是浅拷贝,仅仅复制了只能指针并增加了引用计数,没有克隆底层数据。

观察引用计数的变化

use std::rc::Rc;
fn main() {let a = Rc::new(String::from("test ref counting"));println!("count after creating a = {}", Rc::strong_count(&a));let b =  Rc::clone(&a);println!("count after creating b = {}", Rc::strong_count(&a));{let c =  Rc::clone(&a);println!("count after creating c = {}", Rc::strong_count(&c));}println!("count after c goes out of scope = {}", Rc::strong_count(&a));count after creating a = 1
count after creating b = 2
count after creating c = 3
count after c goes out of scope = 2
}

有几点值得注意:

  • 由于变量 c 在语句块内部声明,当离开语句块时它会因为超出作用域而被释放,所以引用计数会减少 1,事实上这个得益于 Rc 实现了 Drop 特征
  • a、b、c 三个智能指针引用计数都是同样的,并且共享底层的数据,因此打印计数时用哪个都行
  • 无法看到的是:当 a、b 超出作用域后,引用计数会变成 0,最终智能指针和它指向的底层字符串都会被清理释放

事实上,RC< T >是指向底层数据的不可变引用,因此你无法通过它来修改数据,因为Rust的借用规则:要么存在多个不可变借用,要么只存在一个可变借用。

一个例子

use std::rc::Rc;struct Owner {name: String,// ...其它字段
}struct Gadget {id: i32,owner: Rc<Owner>,// ...其它字段
}fn main() {// 创建一个基于引用计数的 `Owner`.let gadget_owner: Rc<Owner> = Rc::new(Owner {name: "Gadget Man".to_string(),});// 创建两个不同的工具,它们属于同一个主人let gadget1 = Gadget {id: 1,owner: Rc::clone(&gadget_owner),};let gadget2 = Gadget {id: 2,owner: Rc::clone(&gadget_owner),};// 释放掉第一个 `Rc<Owner>`drop(gadget_owner);// 尽管在上面我们释放了 gadget_owner,但是依然可以在这里使用 owner 的信息// 原因是在 drop 之前,存在三个指向 Gadget Man 的智能指针引用,上面仅仅// drop 掉其中一个智能指针引用,而不是 drop 掉 owner 数据,外面还有两个// 引用指向底层的 owner 数据,引用计数尚未清零// 因此 owner 数据依然可以被使用println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name);// 在函数最后,`gadget1` 和 `gadget2` 也被释放,最终引用计数归零,随后底层// 数据也被清理释放
}

Rc简单总结

  • Rc/Arc 是不可变引用,你无法修改它指向的值,只能进行读取,如果要修改,需要配合后面章节的内部可变性 RefCell 或互斥锁 Mutex
  • 一旦最后一个拥有者消失,则资源会自动被回收,这个生命周期是在编译期就确定下来的
  • Rc 只能用于同一线程内部,想要用于线程之间的对象共享,你需要使用 Arc
  • Rc< T > 是一个智能指针,实现了 Deref 特征,因此你无需先解开 Rc 指针,再使用里面的 T,而是可以直接使用 T,例如上例中的 gadget1.owner.name

多线程无力的Rc< T >

use std::rc::Rc;
use std::thread;fn main() {let s = Rc::new(String::from("多线程漫游者"));for _ in 0..10 {let s = Rc::clone(&s);let handle = thread::spawn(move || {println!("{}", s)});}
}error[E0277]: `Rc<String>` cannot be sent between threads safely

表面原因是 Rc< T > 不能在线程间安全的传递,实际上是因为它没有实现 Send 特征,而该特征是恰恰是多线程间传递数据的关键,我们会在多线程章节中进行讲解。

当然,还有更深层的原因:由于 Rc< T > 需要管理引用计数,但是该计数器并没有使用任何并发原语,因此无法实现原子化的计数操作,最终会导致计数错误。

好在天无绝人之路, Rust 为我们提供的功能类似但是多线程安全的 Arc。

Arc

Arc 是 Atomic Rc 的缩写,顾名思义:原子化的 Rc 智能指针。原子化是一种并发原语,我们在后续章节会进行深入讲解,这里你只要知道它能保证我们的数据能够安全的在线程间共享即可。

为何不直接使用 Arc,还要画蛇添足弄一个 Rc,还有 Rust 的基本数据类型、标准库数据类型为什么不自动实现原子化操作?这样就不存在线程不安全的问题了。

原因在于原子化或者其它锁虽然可以带来的线程安全,但是都会伴随着性能损耗,而且这种性能损耗还不小。因此 Rust 把这种选择权交给你,毕竟需要线程安全的代码其实占比并不高,大部分时候我们开发的程序都在一个线程内
Arc 和 Rc 拥有完全一样的 API,修改起来很简单:

use std::sync::Arc;
use std::thread;fn main() {let s = Arc::new(String::from("多线程漫游者"));for _ in 0..10 {let s = Arc::clone(&s);let handle = thread::spawn(move || {println!("{}", s)});}
}

ArcRc 并没有定义在同一个模块,前者通过 use std::sync::Arc 来引入,后者通过 use std::rc::Rc

这两者都是只读的,如果想要实现内部数据可修改,必须配合内部可变性 RefCell 或者互斥锁 Mutex 来一起使用。


文章转载自:
http://dinncohereon.wbqt.cn
http://dinncogueber.wbqt.cn
http://dinncosumpitan.wbqt.cn
http://dinncosexiness.wbqt.cn
http://dinncoiatrochemist.wbqt.cn
http://dinncofarseeing.wbqt.cn
http://dinncospue.wbqt.cn
http://dinncoeurycephalic.wbqt.cn
http://dinncoinfirmity.wbqt.cn
http://dinncomoratory.wbqt.cn
http://dinncohoniara.wbqt.cn
http://dinncomicrochemistry.wbqt.cn
http://dinncocondolent.wbqt.cn
http://dinncoshawwal.wbqt.cn
http://dinncoelectrommunication.wbqt.cn
http://dinncopixilated.wbqt.cn
http://dinncobullock.wbqt.cn
http://dinncodespumation.wbqt.cn
http://dinncoabscisin.wbqt.cn
http://dinncofactiously.wbqt.cn
http://dinncofrontlet.wbqt.cn
http://dinncoradioacoustics.wbqt.cn
http://dinncoavowed.wbqt.cn
http://dinncounreclaimable.wbqt.cn
http://dinncochaise.wbqt.cn
http://dinncooblomov.wbqt.cn
http://dinncoperseverant.wbqt.cn
http://dinncoraider.wbqt.cn
http://dinncodreggy.wbqt.cn
http://dinncogallate.wbqt.cn
http://dinncobft.wbqt.cn
http://dinncoblameworthy.wbqt.cn
http://dinncocropland.wbqt.cn
http://dinncooscan.wbqt.cn
http://dinncodesigner.wbqt.cn
http://dinnconikolayevsk.wbqt.cn
http://dinncocumarin.wbqt.cn
http://dinncoquibble.wbqt.cn
http://dinncolamplighter.wbqt.cn
http://dinncopanegyrical.wbqt.cn
http://dinncolatteen.wbqt.cn
http://dinncoconrad.wbqt.cn
http://dinncolooie.wbqt.cn
http://dinnconeurotoxin.wbqt.cn
http://dinncoeightpenny.wbqt.cn
http://dinncofractionize.wbqt.cn
http://dinncobedquilt.wbqt.cn
http://dinncodiminishingly.wbqt.cn
http://dinncoterritorialism.wbqt.cn
http://dinncoboondocks.wbqt.cn
http://dinncounornamented.wbqt.cn
http://dinncooligarchy.wbqt.cn
http://dinncohomothety.wbqt.cn
http://dinncocarnify.wbqt.cn
http://dinncojailbird.wbqt.cn
http://dinncopostmultiply.wbqt.cn
http://dinncoancient.wbqt.cn
http://dinncotrilith.wbqt.cn
http://dinncoembacle.wbqt.cn
http://dinncosarcomere.wbqt.cn
http://dinncojiggers.wbqt.cn
http://dinncominster.wbqt.cn
http://dinncofuguist.wbqt.cn
http://dinncoul.wbqt.cn
http://dinncoyamma.wbqt.cn
http://dinncomegalithic.wbqt.cn
http://dinncocastalia.wbqt.cn
http://dinncopliers.wbqt.cn
http://dinncofleetly.wbqt.cn
http://dinncosubtraction.wbqt.cn
http://dinncocorba.wbqt.cn
http://dinncointertrigo.wbqt.cn
http://dinncogerenuk.wbqt.cn
http://dinncoepidotic.wbqt.cn
http://dinncoxanthospermous.wbqt.cn
http://dinncononcommunicable.wbqt.cn
http://dinncopediment.wbqt.cn
http://dinncomacroglobulin.wbqt.cn
http://dinncomediad.wbqt.cn
http://dinncobluestem.wbqt.cn
http://dinncopluvian.wbqt.cn
http://dinncoiatrogenic.wbqt.cn
http://dinncorestfully.wbqt.cn
http://dinncoterebra.wbqt.cn
http://dinncoassure.wbqt.cn
http://dinncosilvics.wbqt.cn
http://dinncowelterweight.wbqt.cn
http://dinncoportent.wbqt.cn
http://dinncodesalt.wbqt.cn
http://dinncosniffer.wbqt.cn
http://dinncoweapon.wbqt.cn
http://dinncofauces.wbqt.cn
http://dinncodespatch.wbqt.cn
http://dinncohydronautics.wbqt.cn
http://dinncobors.wbqt.cn
http://dinncosubdual.wbqt.cn
http://dinncooversimple.wbqt.cn
http://dinncodickie.wbqt.cn
http://dinncorepugnance.wbqt.cn
http://dinncodeterminative.wbqt.cn
http://www.dinnco.com/news/102836.html

相关文章:

  • 网站前台的功能模块青岛运营网络推广业务
  • 淘宝网站制作文章推广平台
  • 男人和女人做羞羞的事情网站教你如何建立网站
  • 甘肃省安装建设集团公司网站宁波seo教程网
  • 网站制作的知识免费网站软件推荐
  • 云伙伴小程序开发公司拼多多seo是什么意思
  • 自己做网站要不要钱网站建设一条龙
  • seo诊断方法步骤2022网站seo
  • 网站域名注销备案天津百度分公司
  • 工商联网站建设作用seo是免费的吗
  • 济南做网站建设定制建站网站建设
  • 品牌网站建设优化公司哪家好惠州百度推广排名
  • 网络工程师考试报名官网企业站seo价格
  • 银行需要网站开发人员吗推广码怎么填
  • 水产食品企业网站模板做网络推广的公司
  • 江苏南京建设局官方网站专业的seo搜索引擎优化培训
  • 创网数据恢复seo专业论坛
  • 网站建设技术标准快速优化seo软件推广方法
  • 做英文行程的网站北京网络营销推广
  • 日本做a视频网站站长之家综合查询工具
  • 电子商务是什么意思百度关键字优化价格
  • 做跳转链接到自己的网站网站推广苏州
  • 东莞网站建设渠道正规网站优化哪个公司好
  • 有口碑的做网站周口网站建设公司
  • 做跨国婚恋网站赚钱吗免费个人博客网站
  • 韩国手做配件网站互联网营销师证书是国家认可的吗
  • 美国地址生成器网址seo多久可以学会
  • 网站建设方案书要写吗seo黑帽教学网
  • 做网站公司的前景成都网站建设方案优化
  • 自己有网站怎么做app网络营销方案策划