如何从主函数外部提前退出 Rust 程序?

Posted

技术标签:

【中文标题】如何从主函数外部提前退出 Rust 程序?【英文标题】:How do I exit a Rust program early from outside the main function? 【发布时间】:2014-03-01 10:32:50 【问题描述】:

我正在用 Rust 编写 bash 克隆。当用户键入exit 时,我需要退出我的程序。在我的程序之前的迭代中,在我添加更复杂的功能之前,我使用return 来退出提示用户输入的循环。这个逻辑现在在一个函数中,因为我实现内置 shell 函数的方式,所以当我 return 它只是跳出函数回到控制循环,而不是短路控制循环并结束程序。

我意识到当用户键入 exit 并退出循环时我可能会返回一个布尔值,但我至少想知道 Rust 是否有办法提前终止程序,类似于 Java 的 System.exit(),如这对于某些类型的程序很有用。

【问题讨论】:

不,没有安全的方法可以提前终止 Rust 程序。使每项任务完全放松(返回或失败)是唯一的方法。 【参考方案1】:

Rust 1.0 稳定版

std::process::exit() 正是这样做的——它使用指定的退出代码终止程序:

use std::process;

fn main() 
    for i in 0..10 
        if i == 5 
            process::exit(1);
        
        println!("", i);
    

此函数会导致程序立即终止,而无需展开和运行析构函数,因此应谨慎使用。

替代(不推荐)解决方案

您可以直接使用 C API。将libc = "0.2" 添加到Cargo.toml,并且:

fn main() 
    for i in 0..10 
        if i == 5 
            unsafe  libc::exit(1); 
        
        println!("", i);
    

Rust 编译器无法验证调用 C 函数,因此这需要 unsafe 块。程序使用的资源不会被正确释放。这可能会导致诸如挂起套接字之类的问题。 据我了解,退出程序的正确方法是以某种方式终止所有线程,然后进程将自动退出。

【讨论】:

我试过了,效果很好。不过,如果有办法通过 Rust 而不是通过 C 库来做到这一点,那就太好了。谢谢! 使用libc::exit 是一个坏主意。它不会干净地终止该过程,并且可能会危险地破坏事情。正常的 Rust 进程结论必须涉及堆栈展开以便调用析构函数,而 exit(3) 的结论方法完全不同,不涉及堆栈展开。因此,如果您有诸如打开文件之类的东西,它们可能不会被刷新和关闭,TCP 绑定套接字可能无法正确释放(这意味着您无法绑定到套接字,直到超时到期,可能一分钟左右),&c。 —libc::exit 基本上相当于一个段错误,而不是一个干净的退出。 @ChrisMorgan,是的,我期待这样的事情。但我找不到其他方法。 Rust 是否提供了一种干净地终止当前任务而不会失败的方法?还是另一种停止该过程的方法?编辑:哦,对不起,没有看到你对这个问题的评论。真可惜…… @ChrisMorgan 套接字绑定由操作系统处理;一旦你退出,它就会清理干净。您可以立即重新绑定。不过,未刷新的文件缓冲区确实有效。 @VladimirMatveev 我在使用 exit() 时遇到编译错误,知道为什么吗? src\main.rs:14:27: 14:28 错误:预期类型,找到1 src\main.rs:14 std::process:exit(1);【参考方案2】:
panic!("Oh no something bad has happened!")

例子:

    if a * g < 0f32  panic!("The arithmetric-geometric mean is undefined for numbers less than zero!"); 

在较旧的文档中,您会认为这是失败的!(“哦,这里没有发生任何不好的事情。”)

由于某种原因,此宏已从失败更改为恐慌。如果必须,恐慌是失败的方式。

[编辑] 对不起。看起来您应该测试字符串“exit”的输入,这取决于您如何接受输入(按行或按参数)。然后你可以让程序在检测到退出的情况下跳出循环。

例子:

loop 
    if exit_found  break 
    else 
        // your thing, which also looks for exit_found
    

【讨论】:

请注意,panic! 所做的只是优雅地终止当前任务。如果该功能当前不在主要任务上,则panic! 不会exit 程序。即使是这样,它也与exit 不同,因为panic! 将使用任意代码运行析构函数。 失败!被重命名为恐慌!在这个 RFC 中:github.com/rust-lang/rfcs/blob/…

以上是关于如何从主函数外部提前退出 Rust 程序?的主要内容,如果未能解决你的问题,请参考以下文章

从主函数向线程发送信号?

C语言如何提前退出所调用的子函数?

如何从主项目c ++加载DLL

2. 用一个函数来实现将一行字符串中最长的单词输出。此行字符从主函数传递给该函数。C语言高手快出现

Postgresql 在另一个函数中调用一个函数,从主函数传递一个参数

PyQt5 从主模块外部实时登录 QTextedit