Rust语言:安全地并发
http://www.csdn.net/article/2014-02-26/2818556-Rust
http://www.zhihu.com/question/20032903
Rust是近两年Mozilla正在开发的一种新编程语言,以并发、安全和实用为口号,主要使用场景是系统编程,用来取代C++语言的角色。它有颇多新颖之处,能帮助我们了解编程语言设计的流行趋势。
Rust是近两年Mozilla正在开发的一种新编程语言,它以并发、安全和实用为口号,主要使用场景是系统编程,用来取代C++语言的角色。由于Rust还在快速的开发和演进中,每个版本都会产生一些不兼容的变更,现在也许并非是学习这门语言细节,并真正使用它的最佳时机。不过,这并不影响我们了解Rust语言:作为多年来鲜有的新系统编程语言,它有颇多新颖之处,也可以帮助我们了解一些编程语言设计的流行趋势。
并发
与现在流行的很多新语言一样,Rust在语言层面支持了绿色线程(Green threads)——Task。Task作为并发执行的单元,是用户空间的“线程”,创建和调度成本较低,可以大量共存。Task之间通过消息传递通信,没有直接共享数据。从最近的流行趋势来看,绿色线程几乎已成为并发方案大战的最终赢家。除了Rust,之前流行的Go、Erlang、Python的Gevent,以及最近Clojure世界里正在发展的core.async,采用的都是这种绿色线程模式。
绿色线程的程序与传统多线程程序的写法几乎一致。在编写服务器程序时,与事件驱动的回调机制相比,编写更简单、表义更清晰。当并发任务增多时,传统的多线程程序由于启动线程和调度线程的成本高而使系统整体性能降低。而绿色线程可以基本不受限制,随意创建。Rust文档指出,在32位系统上可以支持数十万个Task同时存在。
Task也是Rust程序的基础单元,一个Rust进程由多个并行的Task组成,main函数本身也是一个Task。Task之间通过一个(Port, Chan)元组传递数据。Port和Chan相当于管道的两端,Port用于取数据,Chan用于发送数据。下面的例子里,我们通过do spawn语法(类似Ruby的block语法),启动一个新Task,并打印收到的数据。

引用系统
Rust语言设计的核心是安全性(这里安全性是指Safety,而非Security)。Rust希望通过语言的机制和编译器的功能,把程序员易于犯错、不易检查的问题解决在编译期,避免运行时的Segmentation Fault。Rust的设计可以说是处处小心。Clojure语言强调可变性给编程带来的复杂性,在Rust语言中,设计者对这点也有格外的重视。除非特别声明为mut,所有Rust的局部变量默认都是不可变的,对不可变变量值的修改会导致编译器直接报错。Rust的安全性还通过独有的引用类型系统来实现。
Rust语言中对内存块的引用类型叫做box。最新版本的Rust在语言层面只保留了一种owned box,它在使用时具有一种所有权(Ownership)的概念,只有具有所有权的变量才可以访问这段内存。owned box在同一时刻只允许一个变量作为所有者,它的变量赋值称为move。一旦owned pointer被赋值,用户就无法通过原先的引用访问这块数据,这种错误会在编译时检查。下面是一个简单的例子。

~代表owned box,这里我们把一个包含值为50的owned box赋给owned pointera。然后把a的所有权通过赋值的形式move给b。最后我们试图通过*a访问这个值。在C语言里,这时a和b同时指向统一块内存,可以通过*a访问到这里的值。但Rust的所有权机制给予了这段内存额外的保护。编译这段程序将失败:

编译器会明确地指出错误的引用在何处被move。事实上所有owned box的生命周期管理都是直接在编译时完成的,编译器通过静态检查跟踪使用情况,完成内存开辟和回收。这是Rust确保编程正确、安全的重要手段。
新版本的Rust在标准库中提供std::rc::Rc(引用计数)和std::gc::Gc(垃圾回收)类型,取代了原先的managed box,用来提供可以有限共享的引用类型。
在Task间传递数据,如果要避免数据拷贝,也有专门的引用类型:用于不可变数据的(atomically reference counted,原子的引用计数类型),以及用于可变数据的(带读写锁的原子引用计数类型)。在操作可变数据时,通过内在的读写锁控制对共享数据的访问,从而在API层面实现安全性。

Rust谨慎地定义如此繁多、各具功能的引用类型,就是希望用户在编程过程中,根据应用场景、引用的功能职责,选择合适的类型,进而在引用类型系统和编译器的保护下,减少在运行时出错的机会。这一点也和Clojure的4种引用类型的设计初衷类似,不过Clojure并不能提供太多编译时的安全保护。
更多
篇幅所限,我只选择了Rust最具特点的两个部分介绍。Rust是一门特点鲜明、设计精巧的语言,而绝非普通的“又一门编程语言”。在语法层面,它包含了模式匹配、闭包、泛型等流行功能,作为系统编程语言,使用的舒适度不亚于脚本语言。另外还可以通过FFI(Foreign Function Interface)调用已有的C语言库,满足了实用性的需要。
如果你也开始对这门新语言感兴趣,可以:
- 通过它的文档学习最新版本的语法和细节;
- 加入rust-dev邮件列表了解开发者的讨论;
- 关注Rust项目代码仓库;
- 关注Delicious和Reddit上流行的Rust链接;
- 关注TheweekinRust,介绍每周Rust语言正在发生的变化(http://cmr.github.io/)。
作者孙宁,AVOS Cloud高级工程师,负责服务器端开发。Clojure语言爱好者,社区活跃成员,开发维护了多个Clojure开源项目。
Rust语言:安全地并发的更多相关文章
- 【译】Rust,无畏并发
原文链接:https://dev.to/imaculate3/fearless-concurrency-5fk8 > 原文标题:That's so Rusty! Fearless concurr ...
- Rust语言
Rust语言 https://doc.rust-lang.org/stable/book/ http://www.phperz.com/article/15/0717/141560.html Rust ...
- 半个月使用rust语言的体验
从第一次下载rust语言的编译器到今天刚好第14天. 简单说一下对这个语言的感觉吧. 一.性能 把以前用java写的一个中文地址切分的算法,用rust重新实现了一下(https://github.co ...
- Atitit.rust语言特性 attilax 总结
Atitit.rust语言特性 attilax 总结 1. 创建这个新语言的目的是为了解决一个顽疾:软件的演进速度大大低于硬件的演进,软件在语言级别上无法真正利用多核计算带来的性能提升.1 2. 不会 ...
- 5分钟APIG实战: 使用Rust语言快速构建API能力开放
序言:Rust语言简介 参与过C/C++大型项目的同学可能都经历过因为Null Pointer.Memory Leak等问题“被” 加班了不知道多少个晚上.别沮丧,你不是一个人,Mozilla Fir ...
- 微软看上的Rust 语言,安全性真的很可靠吗
摘要:近几年,Rust语言以极快的增长速度获得了大量关注.其特点是在保证高安全性的同时,获得不输C/C++的性能.在Rust被很多项目使用以后,其实际安全性表现到底如何呢? 近几年,Rust语言以极快 ...
- Rust语言之HelloWorld Web版
Rust语言之HelloWorld Web版 下面这篇文章值得仔细研读: http://arthurtw.github.io/2014/12/21/rust-anti-sloppy-programmi ...
- Rust语言之HelloWorld
Rust语言之HelloWorld 参考文档: http://doc.crates.io/guide.html 1 什么是Cargo 相当于maven/ant之于java, automake之于c, ...
- Go语言的并发
一.Go语言中Goroutine的基本原理 Go语言里的并发指的是能让某个函数独立于其他函数运行的能力. Go语言的goroutine是一个独立的工作单元, Go 语言的并发同步模型来自一个叫作通信顺 ...
随机推荐
- hdu2128之BFS
Tempter of the Bone II Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 98304/32768 K (Java/ ...
- cocos2d&cocos2dx学习资源
汇总一下自己学习Cocos2d和cocos2dx认为比較好的一些资源: 书籍: <iPhone&iPad cocos2d游戏开发实战> Steffen Itterheim < ...
- PHP读取文件头(2字节)判断文件类型(转)
看到此标题或许你会说是否是多此一举,直接判断扩展名不就知道文件类型了吗,但是扩展名很容易伪造,这样就绕过了判断.大部分的文件都会将一个特殊的数字或字符存放在文件的特定位置里(开始处的2个字节) /** ...
- Java语言基础(二)
Java语言基础(二) 一.变量续 (1).变量有明确的类型 (2).变量必须有声明,初始化以后才能使用 (3).变量有作用域,离开作用域后自动回收 变量作用域在块内有效 (4).在同一定义域中变量不 ...
- ckeditor 敏感词标记显示处理方法
直接在原型添加方法: (function () { /* * 取消所有高亮 */ CKEDITOR.editor.prototype.CancleSensitiveWordsHighlight = f ...
- Java基础知识强化01:short s = 1; s = s + 1;与short s = 1; s += 1;
1.short s = 1; s = s + 1;有没有问题?如果有怎么解决? short s = 1; s += 1;有没有问题?如果有怎么解决? 2.理解: short s=1; s=s+ ...
- 剑指offer: 38 数字在排序数组中出现的次数
题目描述 统计一个数字在排序数组中出现的次数.例如输入排序数组{1,2,3,3,3,3,4,5} 和数字3,输出4. 思路如下 1. 预估时间复杂度,最复杂情况是,顺序扫描,统计K出现的次数,时间复杂 ...
- CSS3 变形小结
为原始大小 b:纵向扭曲,0为不变 c :横向扭曲,0不变 d:垂直伸缩量,1为原始大小 e:水平偏移量,0为初始位置 f :垂直偏移向,0是初始位置 Ø原点 transform-origin() ...
- 把nc v6的源码看懂
看懂nc v6的源码! 碧桂园全部的正式环境的补丁都在我手里. 2015-11-18 2:33 谢谢两位一起努力的兄弟 谢谢超哥,谢谢祈冰哥,谢谢连老师,陈明大哥,谢谢龙哥,珍玉,谢谢廖生哥,谢谢林春 ...
- PHP面向对象的基本写法(区别于java)
<?php /** * 这是一个人的对象 */ class ClassName { public $name; public $age; public $sex; public static $ ...