How can I cause a panic on a thread to immediately end the main thread?

前端 未结 2 1795

In Rust, a panic terminates the current thread but is not sent back to the main thread. The solution we are told is to use join. However, this blocks the curren

2条回答
  •  温柔的废话
    2020-12-11 03:32

    I tried to force my code to stop processing when any of threads panicked. The only more-or-less clear solution without using unstable features was to use Drop trait implemented on some struct. This can lead to a resource leak, but in my scenario I'm ok with this.

    use std::process;
    use std::thread;
    use std::time::Duration;
    
    
    static THREAD_ERROR_CODE: i32 = 0x1;
    static NUM_THREADS: u32 = 17;
    static PROBE_SLEEP_MILLIS: u64 = 500;
    
    struct PoisonPill;
    
    impl Drop for PoisonPill {
        fn drop(&mut self) {
            if thread::panicking() {
                println!("dropped while unwinding");
                process::exit(THREAD_ERROR_CODE);
            }
        }
    }
    
    fn main() {
        let mut thread_handles = vec![];
    
        for i in 0..NUM_THREADS {
            thread_handles.push(thread::spawn(move || {
                let b = PoisonPill;
                thread::sleep(Duration::from_millis(PROBE_SLEEP_MILLIS));
                if i % 2 == 0 {
                    println!("kill {}", i);
                    panic!();
                }
                println!("this is thread number {}", i);
            }));
        }
    
        for handle in thread_handles {
            let _ = handle.join();
        }
    }
    

    No matter how b = PoisonPill leaves it's scope, normal or after panic!, its Drop method kicks in. You can distinguish if the caller panicked using thread::panicking and take some action — in my case killing the process.

提交回复
热议问题