在Rust中,恐慌会终止当前线程,但不会发送回主线程 . 我们被告知的解决方案是使用 join
. 但是,这会阻止当前正在执行的线程 . 因此,如果我的主线程产生2个线程,我无法加入它们并立即引起恐慌 .
let jh1 = thread::spawn(|| { println!("thread 1"); sleep(1000000); };
let jh2 = thread::spawn(|| { panic!("thread 2") };
在上面,如果我加入线程1然后在线程2,我将等待1,然后从任一线程收到一个恐慌
虽然在某些情况下我希望当前的行为,但我的目标是默认Go的行为,我可以生成一个线程并让它在该线程上发生恐慌,然后立即结束主线程 . (Go规范还记录了 protect
函数,因此很容易在Go中实现Rust行为) .
2 回答
这可以用不稳定的std::panic::set_handler()来实现 . 您可以设置一个打印恐慌信息的处理程序,然后退出整个过程,如下所示:
尝试评论
set_handler()
,你会看到println!()
行被执行 .但是,由于
process::exit()
的使用,这种方法不允许释放其他线程分配的资源 . 事实上,我不确定Go运行时是否允许这样做;它可能会使用相同的方法来中止流程 .当任何线程恐慌时,我试图强制我的代码停止处理 . 没有使用不稳定特性的唯一或多或少清晰的解决方案是在某些结构上使用
Drop
trait . 这可能会导致资源泄漏,但在我的情况下,我对此感到满意 .无论
b = PoisonPill
如何离开它的范围,正常或在panic!
之后,它的Drop
方法都会启动 . 你可以区分调用者是否使用thread::panicking
恐慌并采取一些行动 - 在我的情况下杀死进程 .