Rust main 函数是如何被执行的

Rust的main函数到底是如何被执行的呢? 让我们看一个关于main函数的示例: 1 2 3 4 5 6 use std::error::Error; fn main() -> Result<(), Box<dyn Error>> { println!("hello world"); Ok(()) } 从这个示例我们可以看到,rust的main函数竟然还可以返回Result枚举,这是为什么?rust到底是如何执行用户定义的main函数的呢? 接下来让我们对rust的源码进行剖析,看一看rust到底是如何运行main函数的。 Rust 运行时 首先,在几乎所有的语言中(目前我不知道哪个语言会不进行处理),在执行用户的main函数之前都需要进行一些初始化工作,比如分配堆栈、创建并绑定主线程、初始化通用寄存器、初始化GC等等。 而rust也不例外,也会在实际调用用户执行的main之前进行一些初始化的操作。 你没看错,rust也是有运行时的,只不过这个运行时没有GC,非常的轻量级,主要是执行上面所说的初始化操作以及对main函数的执行和收尾。 让我们先从init开始: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // 在执行 main 之前执行 unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { #[cfg_attr(target_os = "teeos", allow(unused_unsafe))] unsafe { // 实际的资源初始化逻辑 sys::init(argc, argv, sigpipe) }; // 设置主线程,并设置一个名字 let thread = Thread::new_main(); thread::set_current(thread); } // 运行时只会执行一次 cleanup。 // 在 main 或程序退出的时候执行 // NOTE: 当程序被终止的时候,不能保证执行 cleanup // (终止是 kill 等强制终止,或段错误等行为,程序无法继续执行,资源由操作系统进行回收) pub(crate) fn cleanup() { static CLEANUP: Once = Once::new(); CLEANUP.call_once(|| unsafe { // 刷新 stdout 缓冲区的数据,并禁用缓冲区 crate::io::cleanup(); // SAFETY: 通过 Once 保证,只会执行一次 cleanup sys::cleanup(); }); } 系统资源的初始化和清理在 sys::init 和 sys::cleanup 中 sys::init 在ffi中不保证被调用 sys::init 的源码不是算复杂,主要是保证打开标准输入输出流、初始化栈,感兴趣的可以自行阅读源码 现在我们终于可以进入重点了,rust对main函数的处理逻辑: ...

2024-09-01 · 4 分钟