如何评价rust提升rust技术

取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?
关注成功!
取消关注取消关注后,将无法收到该知识库相关的知识动态和关注周报哦!确定要取消本知识库的关注吗?
Rust是Mozilla公司推出的一门全新的编程语言,并希望成为一门系统编程语言,运行性能高、避免几乎所有的段错误和保证线程安全。这意味着该语言可以用于建造高效可靠的系统。
知识节点:
我创建的知识图谱,希望大家能喜欢
个人知识图谱:
个人知识图谱:
我创建的知识图谱,希望大家能喜欢
个人知识图谱:
完成了一个Rust知识图鉴任务&:&&&
完成了全部知识图鉴任务,点亮了
完成了一个Rust知识图鉴任务&:&&&
完成了一个Rust知识图鉴任务&:&&&
完成了一个Rust知识图鉴任务&:&&&
正在加载..
把你认为靠谱的站内外文章提交给本知识库吧。帮助大家,多多益善!
关联知识库
38172&关注者&&&&3748&条收录
28396&关注者&&&&2056&条收录
8401&关注者&&&&1334&条收录
1730&关注者&&&&680&条收录
3951&关注者&&&&393&条收录
6389&关注者&&&&1356&条收录
12112&关注者&&&&1768&条收录
17800&关注者&&&&1517&条收录
24404&关注者&&&&1417&条收录
29713&关注者&&&&578&条收录
2785&关注者&&&&1144&条收录
4774&关注者&&&&847&条收录
39015&关注者&&&&3162&条收录
22117&关注者&&&&982&条收录
5023&关注者&&&&1700&条收录
5205&关注者&&&&1345&条收录查看: 1172|回复: 9
Rust语言是如何实现线程安全的
认证徽章论坛徽章:277
In every talk I have given till now, the question “how does Rust achieve thread safety?”has invariably come up. I usually just give an overview, but this provides a more comprehensiveexplanation for those who are interested
I touched a bit on the
trait. There are other such “marker” traitsin the standard library, and the ones relevant to this discussion are
and .I recommend reading that post if you’re not familiar with Rust wrapper types like
and ,since I’ll be using them as examples
but the concepts explained here are largely independent.
认证徽章论坛徽章:277
For the purposes of this post, I’ll restrict thread safety to mean no data races or cross-thread dangling pointers. Rust doesn’t aim to solve race conditions. However, there are projects which utilize the type system to provide some form of extra safety, for example rust-sessions attempts to provide protocol safety using session types.
These traits are auto-implemented using a feature called “opt in builtin traits”. So, for example, if struct Foo is Sync, all structs containing Foo will also be Sync, unless we explicitly opt out using impl !Sync for Bar {}. Similarly, if struct Foo is not Sync, structs containing it will not be Sync either, unless they explicitly opt in (unsafe impl Sync for Bar {})
This means that, for example, a Sender for a Send type is itself Send, but a Sender for a non-Send type will not be Send. This patte it lets one use channels with non-threadsafe data in a single-threaded context without requiring a separate “single threaded” channel abstraction.
At the same time, structs like Rc and RefCell which contain Send/Sync fields have explicitly opted out of one or more of these because the invariants they rely on do not hold in threaded situations.
认证徽章论坛徽章:277
It’s actually possible to design your own library with comparable thread safety guarantees outside of the compiler — while these marker traits are specially treated by the compiler, the special treatment is not necessary for their working. Any two opt-in builtin traits could be used here.
Send and Sync have slightly differing meanings, but are very intertwined.
Send types can be moved between threads without an issue. It answers the question “if this variable were moved to another thread, would it still be valid for use?”. Most objects which completely own their contained data qualify here. Notably, Rc doesn’t (since it is shared ownership). Another exception is LocalKey, which does own its data but isn’t valid from other threads. Borrowed data does qualify to be Send, but in most cases it can’t be sent across threads due to a constraint that will be touched upon later.
Even though types like RefCell use non-atomic reference counting, it can be sent safely between threads because this is a transfer of ownership (a move). Sending a RefCell to another thread will be a move and will make it unusable from so this is fine.
认证徽章论坛徽章:277
Sync, on the other hand, is about synchronous access. It answers the question: “if multiple threads were all trying to access this data, would it be safe?”. Types like Mutex and other lock/atomic based types implement this, along with primitive types. Things containing pointers generally are not Sync.
Sync is sort of a crutch to S it helps make other types Send when sharing is involved. For example, &T and Arc&T& are only Send when the inner data is Sync (there’s an additional Send bound in the case of Arc&T&). In words, stuff that has shared/borrowed ownership can be sent to another thread if the shared/borrowed data is synchronous-safe.
RefCell, while Send, is not Sync because of the non atomic reference counting.
Bringing it together, the gatekeeper for all this is thread::spawn(). It has the signaturepub fn spawn&F, T&(f: F) -& JoinHandle&T& where F: FnOnce() -& T, F: Send + 'static, T: Send + 'static复制代码
认证徽章论坛徽章:277
Admittedly, this is confusing/noisy, partially because it’s allowed to return a value, and also because it returns a handle from which we can block on a thread join. We can conjure a simpler spawn API for our needs though:pub fn spawn&F&(f: F) where F: FnOnce(), F: Send + 'static复制代码which can be called like:let mut x = vec![1,2,3,4];
// `move` instructs the closure to move out of its environment
thread::spawn(move || {
& &x.push(1);
// x is not accessible here since it was moved复制代码In words, spawn() will take a callable (usually a closure) that will be called once, and contains data which is Send and 'static. Here, 'static just means that there is no borrowed data contained in the closure. This is the aforementioned constraint that prevents the sharing of borrowed without it we would be able to send a borrowed pointer to a thread that could easily outlive the borrow, causing safety issues.
认证徽章论坛徽章:277
There’s a slight nuance here about the closures — closures can capture outer variables, but by default they do so by-reference (hence the move keyword). They autoimplement Send and Sync depending on their capture clauses. For more on their internal representation, see huon’s post. In this case, x was captured by- i.e. as Vec&T& (instead of being similar to &Vec&T& or something), so the closure itself can be Send. Without the move keyword, the closure would not be `‘static’ since it contains borrowed content.
Since the closure inherits the Send/Sync/'static-ness of its captured data, a closure capturing data of the correct type will satisfy the F: Send+'static bound.
Some examples of things that are allowed and not allowed by this function (for the type of x):
认证徽章论坛徽章:277
1. Vec&T&, Box&T& are allowed because they are Send and 'static (when the inner type is of the same kind)
2. &T isn’t allowed because it’s not 'static. This is good, because borrows should have a statically-known lifetime. Sending a borrowed pointer to a thread may lead to a use after free, or otherwise break aliasing rules.
3. Rc&T& isn’t Send, so it isn’t allowed. We could have some other Rc&T&s hanging around, and end up with a data race on the refcount.
Arc&Vec&u32&& is allowed (Vec&T& is Send and Sync if the inner type is); we can’t cause a safety violation here. Iterator invalidation requires mutation, and Arc&T& doesn’t provide this by default.
4. Arc&Cell&T&& isn’t allowed. Cell&T& provides copying-based internal mutability, and isn’t Sync (so the Arc&Cell&T&& isn’t Send). If this were allowed, we could have cases where larger structs are getting written to from different threads simultaneously resulting in some random mishmash of the two. In other words, a data race.
认证徽章论坛徽章:277
5.& &&&Arc&Mutex&T&& or Arc&RwLock&T&& are allowed. The inner types use threadsafe locks and provide lock-based internal mutability. They can guarantee that only one thread is writing to them at any point in time. For this reason, the mutexes are Sync regardless of the inner T, and Sync types can be shared safely with wrappers like Arc. From the point of view of the inner type, it’s only being accessed by one thread at a time (slightly more complex in the case of RwLock), so it doesn’t need to know about the threads involved. There can’t be data races when Sync types like these are involved.
As mentioned before, you can in fact create a Sender/Receiver pair of non-Send objects. This sounds a bit counterintuitive — shouldn’t we be only sending values which are Send? However, Sender&T& is only Send if T is S so even if we can use a Sender of a non-Send type, we cannot send it to another thread, so it cannot be used to violate thread safety.
认证徽章论坛徽章:277
There is also a way to utilize the Send-ness of &T (which is not 'static) for some Sync T, namely thread::scoped. This function does not have the 'static bound, but it instead has an RAII guard which forces a join before the borrow ends. This allows for easy fork-join parallelism without necessarily needing a Mutex. Sadly, there are problems which crop up when this interacts with Rc cycles, so the API is currently unstable and will be redesigned. This is not a problem with the language design or the design of Send/Sync, rather it is a perfect storm of small design inconsistencies in the libraries.
认证徽章论坛徽章:277
itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有    
 北京市公安局海淀分局网监中心备案编号:10 广播电视节目制作经营许可证:编号(京)字第1149号Rust 1.2再添新功能,你试用了吗?
 作者: IT168 编辑:
  【IT168 编译】系统编程语言Rust再次被更新,其增加了对关联常量的支持,Cargo功能也得到了改善。    Rust是Mozilla开发的注重安全、性能和并发性的编程语言,预期用途包括嵌入其他语言,编写具有特定空间和时间要求的程序,以及编写底层代码,如设备驱动程序和。  对关联常量的支持补充了Rust对关联功能的现有支持,可以与traits,structs和enum相关联。关联的函数是与类型本身相关联的,而不是任何特定实例。Rust 1.20还添加了定义“关联常量”的功能:  struct S  impl Struct {  const ID: u32 = 0;  }  fn main() {  println!(&the ID of Struct is: {}&, Struct::ID);  }  它将常数ID与Struct相关联。  Traits也可以与常量相关联,并且它们还会具有特殊能力,你可以像关联类型一样来关联一个常量,只声明不赋值。Traits的执行者会在运行时赋值。  Rust的包管理器Cargo也已进行了更新,第一个更新是crates.io的秘密身份验证令牌被移动了位置,这意味着它可以被赋予权限级别,同时也可以被系统的其他用户隐藏。在此之前,它是被存储在配置文件中,它只允许某些级别存储。  Cargo的另一个改变是允许存储次级二进制文件,这意味着可以将较大的二进制文件拆分开来存储。  前段时间,Rust语言官方网站发布了一份2017年Rust语言使用情况报告,参与问卷调查的开发者认为Rust需要改进的地方如下,不知这次Rust的更新是否能够让程序员满意。  17%的反馈提到Rust需要提升工效,比如可以更方便地用它创建原型,更容易地进行异步编程,提供更多灵活的数据结构类型。  ·16%的反馈希望Rust具有更好的文档。文档里应该包含入门教程,并提供更多的示例和视频教材。  ·15%的反馈指出Rust需要提供更多的包支持。  ·9%的反馈鼓励Rust提供官方的IDE支持。  ·8%的反馈希望能够降低学习曲线的坡度。  ·其他的反馈包括:更快的编译速度、更多的协作支持、更好的语言互操作性、改进的工具、更友好的错误消息、改进对web assembly的支持等。
IT168企业级在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
标签:至少1个,最多5个
Ownership System是Rust中最独特和吸引人的特性,Rust也是依靠这个特性来实现他的最大的目标:内存安全,所有Rust的开发者都应该详细了解它。
多么浓厚的翻译味道,的确本人学习Rust主要依靠官方的文档(写的很清楚详细),这个系列的文章是我学习Rust的笔记,不完全是翻译官方文档,但大部分内容都是来源于官方文档,但是加上了很多自己的理解、思考和总结,这些笔记呢也都是最基本的概念,暂时并没有深入研究,希望大家在阅读文章的时候能多去看看官方手册,欢迎批评指正和补充。
Ownership(所有权)
Rust有一个非常棒的特点,那就是能在编译的时候检查出大多数安全隐患,这就避免了像C语言一样,编译一切OK,运行时来个Segment Fault,让人不明所以,所以Rust需要一套机制来保证在编译时期发现这些问题,这就是强大的Ownership System,它呢,包含了三个部分:
(后面都会说到),这玩意确实不怎么好理解,得慢慢来。
当声明一个变量绑定的时候,即该变量拥有了对应内存区域的所有权,当该变量超出作用域的时候,它所指向的内存就会被释放。
当然,我们可以将它指派给其他的绑定,就像这样:
//the vector allocates space on the heap
let v=vec![1, 2, 3];
如果在新的绑定之后调用原先的变量,就会得到如下错误:
error: use of moved value: `v`
原因是let v2 =该语句将v所指向的内存区域移交给(move)了v2,之所以报错,官方文档的原话是:
When we move v to v2, it creates a copy of that pointer, for v2. Which means that there would be two pointers to the content of the vector on the heap. It would violate Rust's safety guarantees by introducing a data race. Therefore, Rust forbids using v after we’ve done the move.
意思就是说,现在有两个指针指向了该内存区域,为了避免数据竞争,Rust是不允许使用move后的源变量。
这里有一个问题就是:如果v2超出了它的作用域之后,还能调用v吗?
let v = vec![1,2,3];
println!("v[0] is {} ",v[0]);
结果是依然报错:
error: use of moved value: `v`
也就是说当v2超出其作用域后,v2并不会归还其对应的内存区域的所有权。
对于函数而言也会遇到一样的问题:
fn take(v: Vec&i32&) {
// what happens here isn’t important.
let v = vec![1, 2, 3];
println!("v[0] is: {}", v[0]);
依然会遇到这样的问题
error: use of moved value: `v`
你可能会觉得好像有的变量绑定就不是这样的,比如:
let v = 1;
println!("v is {}",v);
println!("v2 is {}",v2);
这段代码就可以正常输出啊。
这是因为x是i32类型的,它实现了Copy的特性,官方文档的原话是:
In this case, v is an i32, which implements the Copy trait. This means that, just like a move, when we assign v to v2, a copy of the data is made. But, unlike a move, we can still use v afterward. This is because an i32 has no pointers to data somewhere else, copying it is a full copy.
之所以上面的代码没有问题,是因为它是一个完全拷贝,连同数据也复制了一份,不存在两个指针指向同一块内存区域的问题,更谈不上数据竞争,所以这段代码并没有Rust的安全机制,自然也就是允许的,这是和move不同的地方。
如果你想在v2之后还想使用v,可以用如下的方式:
let v = vec![1,2,3];
println!("y[0] is {} ",y[0]);
let v = v2; //交回所有权
println!("v[0] is {} ",v[0]);
这样的语法是不是很麻烦,有没有办法让v2再超出作用域后自己交回所有权呢?有来看看Borrow的概念吧。
持续更新……
3 收藏&&|&&3
你可能感兴趣的文章
1 收藏,1.3k
9 收藏,6.4k
4 收藏,2.8k
本作品 保留所有权利 。未获得许可人许可前,不允许他人复制、发行、展览和表演作品。不允许他人基于该作品创作演绎作品
分享到微博?
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。

我要回帖

更多关于 rust如何拆除建筑 的文章

 

随机推荐