「Rust每日新闻」本周精选 • 第十三期

Words
2304
Reading
11 min
Listen
Play
8y

官方新闻

Rust 1.29.1 发布

$ rustup update stable

修复了str::repeat那个安全问题

原文

rustwasm项目组js-sys 绑定全局JS接口的工作已经完成了

issues done

wasm-pack 大版本发布

wasm-pack 0.5版本发布,这是迄今为止发布的最大的一个版本。截止今天,终于有了一套Rust和WebAssembly梦寐以求的工作流程。

简要:

  • 拥有了独立网站,包含了在线的文档
  • 支持js模块
  • 0.5版本已经将wasm-pack打造成一个集成构建工具,引入了新的命令wasm-pack initwasm-pack testwasm-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适合区块链开发

  • Solana是一种高性能区块链
  • Zcash是一种加密货币
  • Parity是一个核心的区块链基础公司,以太坊相关

文章里包含了视频,以及视频的文字实录。

有空我把它翻译出来。

原文

使用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

runner

原文

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 也有了较大的改进。

redbpf

ingraind

用Rust解决加密挑战

加密挑战

cryptopals-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问题。比如在编写无锁栈的时候:

  1. 栈里包含A和B
  2. 线程M开始pop操作
  3. 线程M 加载 A = top.load()
  4. 线程M 检查 A ==Null
  5. 线程M 测试为false,解引用 B = (* A).next
  6. 线程M被暂停
  7. 线程M弹出堆栈
  8. 线程M释放A
  9. 线程M分配指针C
  10. 线程N push C
  11. 线程N分配指针,并且分配器重用A指针
  12. 线程N push A
  13. 堆栈现在是A/ C/ B
  14. 线程N被挂起并且线程M恢复
  15. 使top.compare_and_swap(A, B)成功
  16. 现在堆栈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的项目

evcxr

指南

emacs支持

理解编译器「入门向」

主要是对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)

debug-here

「油管」 某线下meetup 视频 : Python和Rust在生产环境的集成

视频

Rust实现的进程查看器

基于gtk-rs,跨平台

process-viewer

提供格式化表格打印的库

prettytable-rs

GitHub趋势榜本周新上榜项目

  • TAP-Rust, Test Anything Protocol (TAP) 的Rust实现
  • packed_simd,是对此RFC的实现,可移植的打包SIMD矢量类型
「Rust每日新闻」本周精选 • 第十三期 | Ecency