3

It is expected that threads, on which pthread_detach() was not called, should be pthread_join()ed before the main thread returns from main() or calls exit().

However, what happens when this requirement is not met? What happens when a process terminates when it still contains unjoined and not detached threads?

I would find it odd to learn that these other threads’ resources will not be reclaimed until system reboot. However, if these resources will be reclaimed, then there may be little need to bother about joining or detaching, mightn’t it?

  • In Linux glibc version 2.3 and later actually calls [`exit_group()`](http://man7.org/linux/man-pages/man2/exit_group.2.html) when you return from `main()`, or call `exit()`, `_exit()`, or `_Exit()`; this terminates all threads in the process, and exits the process, releasing all normal system resources. (Only persistent resources, like files, fifos, non-anonymous shared memory and so on, live on.) The real reason you want the threads to exit in an orderly fashion is to ensure they've completed working on persistent data, and not e.g. in the middle of writing to a file. – Nominal Animal May 27 '17 at 05:29
  • 'I would find it odd to learn that these other threads’ resources will not be reclaimed until system reboot' why 'odd'? I would think it odd if they were not released upon process termination. – ThingyWotsit May 27 '17 at 07:21
  • @NominalAnimal 'to ensure they've completed working on persistent data, and not e.g. in the middle of writing to a file' well, apps that rely on such activity for correct operation are in trouble the first time the power fails or it gets shut down by 'kill -9' or Task Manager. If any essential file cleanup is required, it should be done on process startup, not shutdown. – ThingyWotsit May 27 '17 at 08:49
  • @ThingyWotsit: That's just insane. I run parallel simulations, often one subsystem per thread. When I want a simulation to stop early, I like to use a signal. Rather than cause the process (and all threads) to exit at once, I use the signal to set a flag that tells each worker to save their state and exit gracefully. I don't know what programs you run or write, but I hope I'm not relying on any of them... – Nominal Animal May 27 '17 at 09:45
  • @NominalAnimal well, the app I write are guaranteed to restart correctly after power failures and out-of-process kills by administrators. I suppose that, given the fragility of many apps these days, that may be considered to be insanely over-engineered. – ThingyWotsit May 27 '17 at 09:50
  • @ThingyWotsit: Pity that you don't consider *"not losing data"* correct operation, then. – Nominal Animal May 28 '17 at 02:27
  • @NominalAnimal I do have some sympathy with your position. If you, or any other developer, is in the unfortunate position where it is in the spec that a user-code managed shutdown must be peformed whenever possible, then you have to do it. That is far from the norm, however. and many apps can be designed in such a way that a failed write, for whatever reason, does not affect normal operation. The issue I have with your comment is 'The real reason you want the threads to exit in an orderly fashion' and its implication that a user-managed shutdown is always needed and/or desirable. – ThingyWotsit May 28 '17 at 05:31
  • @ThingyWotsit: In my experience, the facility to cleanly exit when requested **is** always needed and desirable. The *user-managed* bit is a small fraction of the cases. I honestly do not see why you have an issue with that assertion, because I cannot even imagine cases where the ability to cleanly exit when requested (on POSIXy systems, due to SIGTERM (services) or SIGHUP (user applications)) would not be useful and desirable. Even stateless services closing their sockets (and thus avoiding SO_LINGER state) makes the system more robust and reliable. – Nominal Animal May 28 '17 at 22:20

2 Answers2

0

It is up to the operating system. Typical modern operating systems will indeed reclaim the memory and descriptors (handles) used by abandoned threads. This is similar to how dynamically allocated memory works: typical modern systems will reclaim it when a process exits, even if the process never explicitly freed the memory. For certain unusual programs, this can be a meaningful performance optimization, because freeing lots of small resources takes time and the OS may be able to do it more quickly.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • "Typical modern operating systems"? I think reclaiming dynamically allocated memory is actually guaranteed by POSIX: ["Memory mappings that were created in the process shall be unmapped before the process is destroyed."](http://pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html#tag_16_01_03_01) –  May 27 '17 at 04:08
0

However, what happens when this requirement is not met? What happens when a process terminates when it still contains unjoined and not detached threads?

On any system with POSIX threads that is not ancient, the non-joined threads simply "evaporate" into space when the SYS_exit system call is performed by the main thread.

I would find it odd to learn that these other threads’ resources will not be reclaimed until system reboot.

They will be.

However, if these resources will be reclaimed, then there may be little need to bother about joining or detaching, mightn’t it?

It depends on what these threads do. The danger is at-exit data races.

In C++, global variables are destructed (usually via atexit or equivalent registration mechanism), FILE handles are deleted, etc. etc.

If non-joined thread tries to access any such resource, it will likely crash with SIGSEGV, possibly producing core dump, and an unclean process exit code, both of which are often quite undesirable.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • 'when the SYS_exit system call is performed by the main thread' - why the 'main thread'?? Surely, any thread will do? – ThingyWotsit May 27 '17 at 07:18
  • It's normal, (in fact essential), for a non-trivial OS to stop the execution of all process threads before releasing any resources that those threads might access. – ThingyWotsit May 27 '17 at 07:19