Difference between -pthread and -lpthread while compiling

-pthread Adds support for multithreading with the pthreads library. This option sets flags for both the preprocessor and linker (man gcc).

while

-lpthread comes in existence while linking there will be no influence while preprocessing.


There is an accepted answer, but, IMO, it doesn't provide enough context and insight. Hence this extra answer.


-lpthread is a solution for a problem that no longer exists (since ~2005).

In the old days there were proprietary implementations of Pthreads API that weren't POSIX-compliant, like LinuxThreads. POSIX standard merely says that if one wants POSIX-compliant behaviour, then one must link with -lpthread, and linking that is required to link a POSIX-compliant implementation of Pthreads API, should there be multiple implementations of it.

There are no multiple implementations of Pthreads API in modern operating systems. And that is why -lpthread no longer serves any purpose.


Compilers like gcc and clang (and, probably, all Linux-compatible compilers) require using -pthread command line option for both compiling and linking POSIX-compliant multi-threaded applications and that is what one must use.

Compiler's documentation is the ultimate authoritive source, any diverging 3rd-party documentation is rather irrelevant.

At compile time, -pthread option manifests that Pthread API is requested (there can be multiple threading APIs, e.g. Solaris Threads) and defines platform-specific macros (_REENTRANT on Linux, _MT on Solaris).

At link time, -pthread links in required libraries (if any) that implement POSIX-compliant Pthreads API behaviour.

The above makes it clear why -lpthread is neither necessary nor sufficient.


GNU libc 2.34:

New applications do not need to link with -lpthread, -ldl, -lutil, -lanl anymore. For backwards compatibility, empty static archives libpthread.a, libdl.a, libutil.a, libanl.a are provided, so that the linker options keep working. Applications which have been linked against glibc 2.33 or earlier continue to load the corresponding shared objects (which are now empty).


-pthread tells the compiler to link in the pthread library as well as configure the compilation for threads.

For example, the following shows the macros that get defined when the -pthread option gets used on the GCC package installed on my Ubuntu machine:

$ gcc -pthread -E -dM test.c > dm.pthread.txt
$ gcc          -E -dM test.c > dm.nopthread.txt
$ diff dm.pthread.txt dm.nopthread.txt 
152d151
< #define _REENTRANT 1
208d206
< #define __USE_REENTRANT 1

Using the -lpthread option only causes the pthread library to be linked - the pre-defined macros don't get defined.

Bottom line: you should use the -pthread option.


Note: the -pthread option is documented as a platform specific option in the GCC docs, so it might not always be available. However, it is available on platforms that the GCC docs don't explicitly list it for (such as i386 and x86-64) - you should use it when available.

Also note that other similar options have been used by GCC, such as -pthreads (listed as a synonym for -pthread on Solaris 2) and -mthread (for MinGW-specific thread support on i386 and x86-64 Windows). My understanding is that GCC is trying to move to using -pthread uniformly going forward.