在Rust中,死机终止当前线程,但不会发送回主线程.我们被告知的解决方案是使用join.但是,这会阻止当前正在执行的线程.如果我的两个主线程不能立即连接,那么我的两个主线程就不能立即连接.

let jh1 = thread::spawn(|| { println!("thread 1"); sleep(1000000); };
let jh2 = thread::spawn(|| { panic!("thread 2") };

在上面的例子中,如果我在线程1上加入,然后在线程2上加入,我将在收到任何一个线程的panic 之前等待1

虽然在某些情况下,我希望当前的行为,但我的目标是默认to Go的行为,我可以生成一个线程,让它在该线程上死机,然后立即结束主线程.(Go规范还记录了protect功能,因此很容易在Go中实现Rust 行为).

推荐答案

Updated for Rust 1.10+, see revision history for the previous version of the answer

很好的一点是,在go中,主线程没有被解开,程序只是崩溃了,但是最初的panic 被报告了.事实上,这就是我想要的行为(尽管理想情况下,各地的资源都会得到适当清理).

这可以通过最近稳定的std::panic::set_hook()功能实现.有了它,你可以设置一个钩子来打印panic 信息,然后退出整个过程,比如:

use std::thread;
use std::panic;
use std::process;

fn main() {
    // take_hook() returns the default hook in case when a custom one is not set
    let orig_hook = panic::take_hook();
    panic::set_hook(Box::new(move |panic_info| {
        // invoke the default handler and exit the process
        orig_hook(panic_info);
        process::exit(1);
    }));

    thread::spawn(move || {
        panic!("something bad happened");
    }).join();

    // this line won't ever be invoked because of process::exit()
    println!("Won't be printed");
}

try 注释set_hook()调用,你会看到println!()行被执行.

然而,由于使用了process::exit(),这种方法将不允许释放由其他线程分配的资源.事实上,我不确定Go运行时是否也允许这样做;它很可能使用相同的方法中止该过程.

Rust相关问答推荐

如何从使用mockall模拟的方法中返回self?

当两者都有效时,为什么Rust编译器建议添加';&;而不是';*';?

MPSC频道在接收器处阻塞

在决定使用std::Sync::Mutex还是使用Tokio::Sync::Mutex时,操作系统线程调度是考虑因素吗?

是否可以使用Rust宏来构建元组的项?

零拷贝按步骤引用一段字节

在Rust中声明和定义一个 struct 体有什么区别

对reqwest提供的这种嵌套JSON struct 进行反序列化

通过异常从同步代码中产生yield 是如何工作的?

为什么实现特征的对象期望比具体对象有更长的生命周期?

Boxing 如何将数据从堆栈移动到堆?

tokio::spawn 有和没有异步块

当推送到 HashMap 中的 Vector 时,类型 `()` 无法取消引用

在 Rust 中查找向量中 dyn struct 的索引

Rust 1.70 中未找到 Trait 实现

如何从 rust 中的同一父目录导入文件

使用 lalrpop 在 rust 中解析由 " 引用的字符串

无法理解 Rust 对临时值的不可变和可变引用是如何被删除的

SDL2 没有在终端键上触发?

为什么在 macOS / iOS 上切换 WiFi 网络时 reqwest 响应会挂起?