官方新闻
Rust 1.29.1 发布
$ rustup update stable
修复了str::repeat那个安全问题
rustwasm项目组js-sys 绑定全局JS接口的工作已经完成了
wasm-pack 大版本发布
wasm-pack 0.5版本发布,这是迄今为止发布的最大的一个版本。截止今天,终于有了一套Rust和WebAssembly梦寐以求的工作流程。
简要:
- 拥有了独立网站,包含了在线的文档
- 支持js模块
- 0.5版本已经将wasm-pack打造成一个集成构建工具,引入了新的命令
wasm-pack init、wasm-pack test和wasm-pack publish
还有其他很多新的功能,详细请看Changelog
官方通告:web-sys crate发布
web-sys是对所有Web API的绑定,包括:
- dom操作
- WebGL
- Web Audio
- 定时器
- fetch
- 等等
未来还会支持WebAssembly的Host Binding,解锁dom操作的性能
另外js-sys功能也100%完成了,它是对所有ECMAScript API的原生绑定,与web-sys不同的是,js-sys是手工编写,而非WebIDL。
原文里还包含了两个demo
Niko办公时间:循环服务
讨论了一个经典的问题:Rust如何处理循环数据? 答案是,不需要循环。
当使用带有GC的语言,比如js,可以这么写:
function setup() {
var directory = {};
var service1 = new Service1(directory);
var service2 = new Service2(directory);
return directory;
}
function Service1(directory) {
self.directory = directory;
directory.service1 = self;
...
}
function Service2(directory) {
self.directory = directory;
directory.service2 = self;
...
}
希望有多个服务,并且可以彼此通信,通过创建directory来存储这些服务对象。directory里存储的对象都可以互相访问。
但是将此代码修改为Rust时,就会陷入困惑:
struct Directory {
service1: Option<Service1>,
service2: Option<Service2>,
}
创建Directory时,Service还不存在,所以使用Option。但是初始化directory之后,Service就永远不可能为None。最大的问题是,该如何管理内存?因为Service1有可能会引用到Service2。
使用Arc或原子类型和锁,可以改善,但还不是最好的办法。
#[derive(Clone)]
struct Directory {
service1: Sender<Message1>,
service2: Sender<Message2>,
}
/// Whatever kind of message service1 expects.
struct Message1 { .. }
/// Whatever kind of message service2 expects.
struct Message2 { .. }
可以使用Sender<Message>类型来解耦,不要通过共享内存来通信,要通过通信来共享内存。
Sender是指Channel中的Sender,利用Channel来实现一个Actor模型,每个service就是一个Actor,Actor之间通过发送消息来相互调用。
Niko使用std::sync::channel来演示这种思想,然后使用Arc、Mutex和ConVar实现了一个简单的自定义Channel。
嵌入式工作组报告 12
简要:
- users.rust-lang.org 论坛现在加入了Embedded 分类
- 可以使用Rust的1.30-beta版本在stable上构建嵌入式二进制文件
- eeprom24x crate发布,用于EEPROM存储芯片的嵌入式兼容驱动器
- Trangar 基于 他自己用Rust实现的ArtNet协议,控制了56个照明设备
- 还有很多基于embedded-hal实现的驱动发布
社区新闻
「长文预警」Solana 、Zcash 和Parity 三家会面讨论为什么Rust适合区块链开发
文章里包含了视频,以及视频的文字实录。
有空我把它翻译出来。
使用Runner来运行小的Rust代码片段
$ cat print.rs
println!("Hello, World!");
$ runner print.rs
Hello, World!
runner对代码片段默认会有main函数包装:
// file.rs
let mut f = File::open("file.rs")?;
let mut buf = String::new();
f.read_to_string(&mut buf)?;
println!("{}",buf);
还可以直接运行代码:
$ runner -i "(0..4).map(|n| 2*n)"
0
2
4
6
总之,就像是一个方便的终端版的playground
Newsboat准备用Rust重写
Newsboat是一个C++实现的RSS/Atom feed 阅读器,目前作者有用Rust重写的计划
感兴趣的可以关注下,应该有学习价值
Rust实现的eBPF工具包发布
BPF 的全称是 Berkeley Packet Filter,顾名思义,这是一个用于过滤(filter)网络报文(packet)的架构。
extended BPF(eBPF),源于 BPF 的全新设计。一方面,它已经为内核追踪(Kernel Tracing)、应用性能调优/监控、流控(Traffic Control)等领域带来了激动人心的变革;另一方面,在接口的设计以及易用性上,eBPF 也有了较大的改进。
用Rust解决加密挑战
Tower Web 0.3 发布
支持async/await和 Handlebars模板渲染
struct MyResource;
impl_web! {
impl MyResource {
#[get("/")]
async fn index(&self) -> String {
let data = await!(load_data());
format!("Data = {}", data)
}
}
}
Tower Web当然还要准备和Warp合并,但在合并之前,作者希望达到一个完成度比较高的抽象。
「专业提示」在使用cargo fmt/rustfmt的时候请使用rustfmt.toml 文件
这样方便与别人协作,直接使用你的配置。即便你使用的是rustfmt默认的配置,也需要放一个空的rustfmt.toml文件,它表示你是希望跟你协作的人也使用rustfmt。
大家怎么看? 我觉得有道理。
博文与库
如何在流行的Rust Crate中发现漏洞
C和Rust的相对性能
「谎话跑得飞快,真相在后面蹒跚而行(falsehood flies, and the truth comes limping after it)」
作者用这句话来描述基准测试,原因有二:
- 难以量化系统的性能
- 即使获得了正确的结果,实际上也是在系统上下文是正确的
所以作者此文并不是另一个基准测试。
测试结果简要概括:
CPU L1 缓存命中率 : Rust 96.9%, C 77.9%, L2缓存Rust表现也比较稳定,但C就不行了
作者又进一步探索了,到底是Rust语言的优势,还是数据结构的优势?
结论:
- Rust的基础数据结构表现非常好,测试结果的差异大部分是数据结构的差异。
- 但因为Rust的所有权机制,迫使开发者不得不仔细优化这些数据结构的实现
Rust是强大的抽象又不损失性能,这并不意味着Rust总是能胜过C,但是你可以通过这篇文章,对Rust有一个正确的看待了。
[延伸阅读 ](Rust中BTreeMap实现机制 http://cglab.ca/~abeinges/blah/rust-btree-case/)
ABA问题和并发回收
编写无锁数据结构就会出现ABA问题。比如在编写无锁栈的时候:
- 栈里包含A和B
- 线程M开始pop操作
- 线程M 加载 A = top.load()
- 线程M 检查 A ==Null
- 线程M 测试为false,解引用 B = (* A).next
- 线程M被暂停
- 线程M弹出堆栈
- 线程M释放A
- 线程M分配指针C
- 线程N push C
- 线程N分配指针,并且分配器重用A指针
- 线程N push A
- 堆栈现在是A/ C/ B
- 线程N被挂起并且线程M恢复
- 使top.compare_and_swap(A, B)成功
- 现在堆栈B和C被泄漏
前 1 - 13步,实际上在栈顶的A值已经发生过了变化。但是到第15步进行CAS操作的时候,将A值换为B,CAS操作没有分辨出A值实际上已经不是之前的A。所以就发生了ABA问题。
ABA问题的本质是内存回收。对于上面的问题,A被弹出以后,就不应该被释放,因为还有B在用着它,也不能被线程N 重用。
所以一般使用 险象指针(hazard pointers,HP)来阻止释放还被其他线程使用的指针。 将来crossbeam-epoch也打算支持险象指针。
所以作者基于这种思想实现了一个crate: lockfree
该库提供了一些无锁数据结构,以及提供API为每个线程都增加一个删除队列,解决ABA问题
Rust 移动开发
该教程是在iOS上面使用Rust构建应用教程,这个系列应该还会包含安卓,可以关注一下
nalgebra-glm发布
GLM(OpenGL Math)是一个流行的线性代数库,主要聚焦于计算机图形。nalgebra-glm从GLM中汲取灵感,为简单的图形应用定义了一个简单易用的API。
一个Rust REPL实现
还包含了一个jupyter 的内核来支持Rust
在Google的仓库里,但不知道算不算Google的项目
理解编译器「入门向」
主要是对Rust编译器工作机制的概要介绍
Concepts: C++下一个重大变化
感觉有点像Rust的 trait
预计C++20里可用
新库:debug-here
是一个rust-gdb的hook,提供了一个宏,可以帮助开发者快速使用GDB进行调试。所以只支持Linux
#[macro_use] extern crate debug_here;
fn factorial(n: usize) -> usize {
let mut res = 1;
debug_here!();
for i in 0..n {
res *= i;
}
res
}
fn main() {
println!("The factorial of 5 is {}!", factorial(5));
}
debug_me::factorial (n=5) at debug-me/src/main.rs:6
6 for i in 0..n {
(gdb)
「油管」 某线下meetup 视频 : Python和Rust在生产环境的集成
Rust实现的进程查看器
基于gtk-rs,跨平台
提供格式化表格打印的库
GitHub趋势榜本周新上榜项目
- TAP-Rust, Test Anything Protocol (TAP) 的Rust实现
- packed_simd,是对此RFC的实现,可移植的打包SIMD矢量类型