views:

159

answers:

3

This question seems like it's probably a duplicate, but I was unable to find one. If I missed a previous question, apologies.

In Java, where I have most of my experience, if your main() forks a thread and immediately returns the process continues to run until all (non-daemon) threads in the process have stopped.

In C++, this appears not to be the case - as soon as the main thread returns the process is terminating with other threads still running. For my current app this is easily solved with the application of pthread_join() but I'm wondering what causes this behavior. Is this compiler (gcc) specific, pthreads specific, or is kind of behavior shared across most/all platforms for which C++ has been implemented? Is this behavior configurable within pthreads (I've looked through the pthread api at the pthread_attr_*() functions and didn't see anything that looked relevant.)?

Completely separate question, but while you're here ... what would one use pthread_detatch() for?

+7  A: 

Yes. In modern linux (more importantly newer versions of GNU libc) exit_group is the system call used when main returns, not plain exit. exit_group is described as follows:

This system call is equivalent to exit(2) except that it terminates not only the calling thread, but all threads in the calling process's thread group.

It is worth noting that current the c++ standard makes no mention of threads, so this behavior is not c++ specific, but instead is specific to your particular implementation. That said, every implementation I've personally seen kills all threads when the main thread terminates.

EDIT: It is also worth noting Jonathan Leffler's answer which points out that the POSIX standard does indeed specify this behavior, so it is certainly normal for an application using pthreads for its threading.

EDIT: To answer the follow up about pthread_detach. Basically it is considered a resource leak if you do not join a non-detached thread. If you have a long running task which you have no need to "wait for", and it just "ends when it ends" then you should detach it which will not have a resource leak when it terminates with no join. The man page says the following:

The pthread_detach() function marks the thread identified by thread as detached. When a detached thread terminates, its resources are automatically released back to the system without the need for another thread to join with the terminated thread.

So a quick and dirty answer is: "when you don't care when it ends, detach it. If another thread cares when it ends and must wait for it to terminate, then don't."

Evan Teran
Note that `exit_group` is the internal call name, and the `exit(2)` it refers to is also the internal system call. If you invoke `exit()` from C, it will call `exit_group`.
bdonlan
@bdonlan: good point, I imagine that this is for backwards compatibility with older applications that still call `exit()`.
Evan Teran
Very thorough answer, thanks! Is behavior generally the same on Windows?
Greg Howell
@gshowell: IIRC windows has the same behavior.
Evan Teran
A: 

This is not compiler specific and is standard behavior; the application terminates when main() exits, so if you want to prevent the application from terminating, you need main() to block until all threads have terminated, which you do by joining those threads. When you invoke pthread_create, it allocates resources for that thread. The resources are not deallocated unless you do a pthread_join (which blocks until the thread terminates) or pthread_detach (which causes the thread to automatically release resources when that thread exits). You should use pthread_detach whenever you launch a background thread that will terminate when its task is completed and for which you do not need to wait.

To make this a little bit more concrete, suppose you have several threads that perform a piece of a computation, and then you aggregate the result in some way. That would be a case where you would use join, because you need the results of the threads to proceed. Now, consider a case where a thread listens on a socket and processes incoming requests, until a flag indicates that the thread should quit. In this case, you would use pthread_detach, since nothing needs the thread to terminate in order to proceed, and so the resources associated with that thread should go away automatically.

Michael Aaron Safyan
+8  A: 

Yes

The POSIX standard says:

§3.297 Process Termination

There are two kinds of process termination:

  1. Normal termination occurs by a return from main(), when requested with the exit(), _exit(), or _Exit() functions; or when the last thread in the process terminates by returning from its start function, by calling the pthread_exit() function, or through cancellation.

  2. Abnormal termination occurs when requested by the abort() function or when some signals are received.

The first normal termination condition applies. (Note that the C++ (1998, 2003) standard says nothing about threads.)


Regarding pthread_detach()

The POSIX standard (again) says:

The pthread_detach() function shall indicate to the implementation that storage for the thread thread can be reclaimed when that thread terminates. If thread has not terminated, pthread_detach() shall not cause it to terminate.

And the rationale says:

The pthread_join() or pthread_detach() functions should eventually be called for every thread that is created so that storage associated with the thread may be reclaimed.

It has been suggested that a "detach" function is not necessary; the detachstate thread creation attribute is sufficient, since a thread need never be dynamically detached. However, need arises in at least two cases:

  1. In a cancellation handler for a pthread_join() it is nearly essential to have a pthread_detach() function in order to detach the thread on which pthread_join() was waiting. Without it, it would be necessary to have the handler do another pthread_join() to attempt to detach the thread, which would both delay the cancellation processing for an unbounded period and introduce a new call to pthread_join(), which might itself need a cancellation handler. A dynamic detach is nearly essential in this case.

  2. In order to detach the "initial thread" (as may be desirable in processes that set up server threads).

Jonathan Leffler
+1 Good answer :-)
Evan Teran
+1 for standards quotes. Appreciated.
Greg Howell
Reading through Process Termination bullet one, how would you arrive in a situation in which the last thread in the process returns, and that last thread is not the main thread returning from main()? Can you pthread_exit() the main thread without terminating the entire process?
Greg Howell
@gshowell: I think you are correct that if the main thread (original thread?) does pthread_exit(), the process as a whole is not terminated until all the other threads also terminate. There is nothing special about the main thread unless it executes a return from the main() function - in my reading of the POSIX manual page entries.
Jonathan Leffler