A little confused with multithreading

@ZiCog @Cerberuser @2e71828 Oh ok so if I understood correctly, even after the main() function ends, the thread that I spawned may still continue its process?

Yes, and this is called detachment. From JoinHandle:

A JoinHandle detaches the associated thread when it is dropped, which means that there is no longer any handle to thread and no way to join on it.

1 Like

Until the operation system kills it, yes. In case of main, this will happen almost immediately, but, as I said before, main isn't special - if you spawn a thread in any function and leave without joining, this thread will run in the background indefinitely.


Let's not talk about "processes". That is a whole other story in operating systems like Linux.

In my experience threads get terminated and cleaned up by the OS when main() exits on Linux.

On the other hand I have worked on systems where main() can exit or crash and burn but any threads it started keep running. Typically embedded systems with very simple run times.

Even in C, main is just another function. On Linux the _start function is provided by libc, and it sets things up before calling main. When main returns, control returns to _start which then runs cleanup code and exentually exit, which tells the OS to terminate the process.

If something registers an atexit handler, there’s a very good chance it’s going to clobber the memory where main’s locals were, while any spawned threads are still running.

1 Like

Is this the same for Windows as well?

That is correct in C main() is just another function.

But the practical upshot is that, at least in Linux, when main exits libc or the OS or whoever does kill all the threads and salvage memory pretty damn quick. There is scope for race conditions as you say.

The same happens in Rust as far as I can tell from my simple experiments.

Good practice dictates you don't do that.

From the std::thread docs, you’re correct about other threads getting terminated automatically:

When the main thread of a Rust program terminates, the entire program shuts down, even if other threads are still running.

Race conditions, however, are one of the things that Rust’s ownership rules are supposed to prevent at compile time. Because there’s a tiny bit of time after main destroys its local variables and before the spawned thread is killed, the other threads is statically prevented from holding a reference to main’s locals.