gpt4 book ai didi

rust - 如何在线程上引起 panic 以立即结束主线程?

转载 作者:行者123 更新时间:2023-12-03 07:56:23 25 4
gpt4 key购买 nike

在 Rust 中, panic 会终止当前线程,但不会发送回主线程。我们被告知的解决方案是使用 join .但是,这会阻塞当前正在执行的线程。因此,如果我的主线程产生 2 个线程,我不能同时加入它们并立即 recover panic 。

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

在上面,如果我在线程 1 上加入,然后在线程 2 上加入,我将在收到来自任一线程的 panic 之前等待 1

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

最佳答案

针对 Rust 1.10+ 进行了更新,请参阅答案的先前版本 的修订历史记录

good point, in go the main thread doesn't get unwound, the program just crashes, but the original panic is reported. This is in fact the behavior I want (although ideally resources would get cleaned up properly everywhere).



这可以通过最近稳定的 std::panic::set_hook() 来实现功能。有了它,你可以设置一个钩子(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");
}

尝试评论 set_hook()呼出,你会看到 println!()行被执行。

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

关于rust - 如何在线程上引起 panic 以立即结束主线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63471172/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com