1

I have the following contrived Rust code:

use std::thread;

const THREAD_COUNT: u8 = 10;

struct DropMe {
    id: u8,
}

impl Drop for DropMe {
    fn drop(&mut self) {
        println!("Dropped item {}", self.id);
    }
}

fn main() {
    let outer_drop_me = DropMe { id: 255 };
    println!(
        "Created instance outside of threads with ID: {}",
        &outer_drop_me.id
    );
    for i in 0..THREAD_COUNT {
        let drop_me = DropMe { id: i };
        thread::spawn(move || {
            println!("Spawned thread {}", drop_me.id);
            // Poor man's substitute for illustrating blocking I/O
            thread::sleep(std::time::Duration::from_millis(500));
            // Poor man's substitute for illustrating a cleanup function
            drop(drop_me);
        });
    }
    // outer_drop_me should be dropped automatically here as it goes out of
    // scope
}

The output of which is as follows:

Created instance outside of threads with ID: 255
Spawned thread 0
Spawned thread 1
Spawned thread 2
Spawned thread 3
Spawned thread 4
Spawned thread 5
Spawned thread 6
Spawned thread 7
Spawned thread 8
Dropped item 255
Spawned thread 9

How can I do cleanup in threads where the code inside those threads may be blocking, but the process is being terminated (e.g. by way of SIGTERM)?

In this contrived example, one could join on the returned thread handles from the spawned threads, but what if join is not available and the child threads are blocking? Do you just resign yourself to forfeiting the cleanup code after the part of the code that may be blocking?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Thane Thomson
  • 403
  • 1
  • 4
  • 14
  • 6
    A leak only happens inside a process; it doesn't make sense to ask if something is leaked "when a process dies". – trent Nov 25 '19 at 18:06
  • @trentcl I would guess that OP means thread, not process. But then, the example code shows the process ending immediately after the thread anyway... – Peter Hall Nov 25 '19 at 18:13
  • No, @trentcl's right. I was thinking about processes (perhaps a noob misunderstanding on my part), but more so about potential untoward consequences outside of a process of not waiting for all child threads to join (not memory leaks per se). – Thane Thomson Nov 25 '19 at 18:20
  • My main concern is actually cleanup within threads when the process dies, but especially from within threads that are running some kind of blocking code where communicating with them from outside isn't possible. – Thane Thomson Nov 25 '19 at 18:23
  • *The output of which is as follows* — that's **one possible** output. Running it myself showed "Created instance outside of threads with ID: 255 Dropped item 255" because the threads never had a chance to run. – Shepmaster Nov 25 '19 at 18:31
  • It looks like your question might be answered by the answers of [Is leaked memory freed up when the program exits?](https://stackoverflow.com/q/2975831/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Nov 25 '19 at 18:32
  • 1
    You don't, period. See [What is the standard way to get a Rust thread out of blocking operations?](https://stackoverflow.com/q/52465480/155423); [How does Rust handle killing threads?](https://stackoverflow.com/q/55228629/155423). – Shepmaster Nov 25 '19 at 18:43
  • See also [How do I gracefully shutdown the Tokio runtime in response to a SIGTERM?](https://stackoverflow.com/q/53458755/155423); [How to catch signals in Rust](https://stackoverflow.com/q/26280859/155423). – Shepmaster Nov 25 '19 at 18:43

0 Answers0