Skip to content
Advertisement

What is the difference between exit() and exit_group()

What is the difference between exit() and exit_group(). Any process that has multiple threads should use exit_group instead of exit?

To answer the question why do you ask – we are having an process that has around forty threads. When a thread is locked up, we automatically exit the process and then restart the process. And we print the backtrace of the thread that was locked up. We wanted to know whether calling exit in this case is any different from exit_group.

From the docs: 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 – However, what is the difference between exiting the process and exiting all the threads. Isn’t exiting process == exiting all the threads.

Advertisement

Answer

All thread libraries I know (e.g. recent glibc or musl-libc) are using the low-level clone(2) system call for their thread implementations (and some C libraries are even using clone to fork a process).

clone is a difficult Linux syscall. Unless you are a thread library implementor, you should not use it directly but only thru library functions (like e.g. pthread_create(3)); see also futex(7) used in pthread_mutex* functions

The clone syscall is used to create tasks: either threads (sharing address space in a multi-threaded process) or processes.

The exit_group syscall is related to exiting these tasks.

In short, you’ll never use directly exit_group or clone. Your libc is doing that for you. So don’t care about exit_group or _Exit; you should use the standard library function exit(3) only, which deals notably with atexit(3) & on_exit(3) registered handlers and flushes <stdio.h> buffers. In the rare cases you don’t want that to happen, use _exit(2) (but you probably don’t need that).

Of course, if you are reimplementing your own libc from scratch, you need to care about exit_group & clone; but otherwise you don’t care about them..

If you care about gory implementation details, dive into the source code of your libc. Details may be libc-version, kernel-version, and compiler specific!

Advertisement