There can be all sorts of timing holes. If you care when the threads have finished, then the threads probably should not be
detached threads at all.
In my experience, asking threads to own and to manage their own resources is usually a recipe for trouble anyway. As is creating a "potentially unlimited" number of threads.
I'd generally structure the program this way:
- The main thread initializes the environment, then creates a fixed pool of worker-threads.
- The worker-threads wait for work (or a termination indicator), do the work, and repeat... staying alive all the time. (A work-queue may build up fron time to time, but the number of employees remains constant.)
- When it's time to go home, the main thread sends an appropriate indication to all of the children, asking them to terminate themselves.
- The main thread then reaps (joins) each thread, continuing this process until all of the dead bodies have been reaped. (Note that no signal is required to indicate that a child has died.)
- The main program cleans up the environment and exits.
"Be nice to your kids." If you structure the program so that things are
too asynchronous, and there's a lot of birthing and dying going on, you've got something that's very tough to debug. Very tough to make
reliable...