Linux 内核准备升级至 Rust 1.77
Linux 6.8 内核已经升级至 Rust 1.75,而最新的补丁则将内核的 Rust 代码迁移到 Rust 1.76,并准备好迎接即将发布的 Rust 1.77。 Rust 1.77 稳定了内核 Rust 代码使用的单字段 "offset_of" 功能,并添加了一个"--check-cfg" 选项,内核 Rust 代码未来可能会过渡到这个选项。这符合 Rust for Linux 跟踪上游 Rust 版本升级的政策,直到确定了所有使用的功能都被认为是稳定的最低版本为止。预计将在即将到来的 Linux 6.9 内核合并窗口中进行对 Rust 1.77 的升级。
极小的 Rust 二进制文件
本文探索如何制作一个极小的 x86_64 Linux Rust 二进制文件,并比较其与纯汇编程序的竞争性。
从一个大小为 3.6 MiB
的起点开始,通过优化和调整,逐步减小二进制文件的大小。优化手段包括去除符号、调整编译参数、替换标准库等。通过去除标准库并直接使用 libc,以及自定义 _start 函数,极大地减小了二进制文件的大小。最终通过调整链接器标志和移除不必要的 ELF sections,将二进制文件的大小降至 400 bytes
,达到了极小化的目标。
Rust 展现出了出色的系统编程能力,即使在 no_std 环境下也能进行嵌入式编程和其他应用领域。Rust 在性能和体积上的优势使其在实际应用中具有广泛的潜力,甚至可以取代一些汇编编写的程序。
FuturesUnordered
以及 future的顺序
FuturesUnordered 是 Rust 中用于并发子任务的强大工具,但如果使用不当,会导致死锁。
两种常见的 FuturesUnordered 使用模式:
- 缓冲流:将工作流表示为 futures 的流,并使用类似
buffered
适配器将其缓冲。 - 范围任务:将工作表示为“在” FuturesUnordered 上“生成”的任务,使用类似
moro
库的 API。
死锁的条件:
- 互斥:每个任务都需要独占资源。
- 等待资源:任务在等待其他资源时持有已分配的资源。
- 不可抢占:资源不能从持有者手中强制移除。
- 循环等待:存在任务链,每个任务都请求链中下一个任务持有的资源。
示例死锁:
使用异步生成器和互斥锁。
async gen {
let mut guard = mutex.lock().await;
yield x;
yield y;
drop(guard);
};
for await elem in iter {
let mut guard = mutex.lock().await;
println!("{}", elem);
drop(guard);
}
预防死锁:
- 通过显式声明并发性来避免控制流中的隐式共享资源。
- 优先使用范围任务而不是缓冲流,因为它们使资源依赖关系更清晰。
- 使用通道时要注意队列大小和循环依赖关系。
- 使用未缓冲通道测试以捕获潜在死锁。
Rust 的优势:
- 所有权和借用可以防止死锁和复杂的同步。
- 范围任务应该集成到运行时中以获得更好的借用支持。
其他注意事项:
- 文章批评了使用大量任意值作为通道大小的做法,因为它隐藏了潜在的死锁。
- 它建议使用利用所有权和借用的模式。
总结
FuturesUnordered 是一个强大的工具,但需要谨慎使用以避免死锁。了解死锁的条件以及如何预防它们,并选择合适的模式来实现并发。Rust 的所有权和借用系统可以帮助防止死锁,并使代码更安全、更可靠。
Inlyne: 无浏览器 markdown 预览工具
Inlyne 是一款利用 GPU 加速的无浏览器工具,帮助您快速查看 Markdown 文件. 目前 0.4 版本发布.
--
From 日报小组 BobQ, FBI小白
社区学习交流平台订阅:
评论区
写评论还没有评论