Undefined reference to pthread_create in Linux
Asked Answered
V

16

541

I picked up the following demo off the web from https://computing.llnl.gov/tutorials/pthreads/

#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS     5

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }
   pthread_exit(NULL);
}

But when I compile it on my machine (running Ubuntu Linux 9.04) I get the following error:

corey@ubuntu:~/demo$ gcc -o term term.c
term.c: In function ‘main’:
term.c:23: warning: incompatible implicit declaration of built-in function ‘exit’
/tmp/cc8BMzwx.o: In function `main':
term.c:(.text+0x82): undefined reference to `pthread_create'
collect2: ld returned 1 exit status

This doesn't make any sense to me, because the header includes pthread.h, which should have the pthread_create function. Any ideas what's going wrong?

Vernita answered 2/11, 2009 at 18:40 Comment(6)
Additionally: depending on the platform, you may need (a) a different compiler for threads, (b) a different libc for threads (i.e. -lc_r), (c) -thread or -threads or other, instead of or in addition to -lpthread.Tappet
Just a little above that example, you'll see a table of the correct compiler commands, whether it be GCC, IBM, etc. 'Employed Russian' is correct.Brewster
Can you please unmark my answer, so that I can delete it (and mark the one that is actually correct, which is the highest-voted one)?Additive
-lpthread is needed during compileTorquemada
solution LDFLAGS= -pthread -lpthreadEverybody
Is pthread_exit(NULL); in main required/good practice ?Paynter
I
920

For Linux the correct command is:

gcc -pthread -o term term.c

In general, libraries should follow sources and objects on command line, and -lpthread is not an "option", it's a library specification. On a system with only libpthread.a installed,

gcc -lpthread ...

will fail to link.

Read this or this detailed explanation.

Ionization answered 3/11, 2009 at 3:44 Comment(11)
+1 this solution worked... otheres did not. Also, suggestion that 'libraries should follow sources and objects' is great advice -- a citation or further explanation would be great.Apollyon
@Apollyon Here is the explanation: webpages.charter.net/ppluzhnikov/linker.htmlIonization
This still errored for me till I put -lpthread at the very end of my command. gcc term.c -lpthreadOiler
I just ran into an issue compiling snortsam on Ubuntu 14.04 which actually has both libpthread.a and libpthread.so. I was getting undefined reference to 'pthread_cancel' and undefined reference to 'pthread_create' errors. I came across this SO post and thought I'd try out Employed Russian's answer. I opened up makesnortsam.sh in VI and ran the command :%s/lpthread/pthread/g to replace lpthread with pthread so that it would use -pthread instead of -lpthread when compiling. I was then able to compile snortsam. Thanks Employed Russian!Clayborne
For anyone using CODEBLOCKS: Add -pthread to Project Build Options -> Linker Settings -> Other linker options.Raul
"On a system with only libpthread.a installed"...... or libpthread.so , right ?Espinosa
To make sure I remember to do this when compiling from the command line like this, I like to create a .sh file with the same name as the program I'm compiling to save the command. Then I just run it when I want to compile. Thanks for the great answer. It's still helping people.Mesomorph
Re: "In general, libraries should follow sources and objects on command line": I understand it in case of e.g. accept, which is not part of the C standard library, but placed in libc.a. So, in case if user defines its own accept and then manually links with libc.a, then the libc.a has to follow the objects (otherwise, accept from libc.a may be used). However: why using -lpthread before the objects leads to "undefined reference to 'pthread_create'"? Why linker cannot find pthread_create?Revisal
@Revisal I've edited the answer with links to the explanation of "why linker cannot ...".Ionization
Thanks. So, per this "since it doesn't need pthread_create, this object file is not included in the link" The question is why linker is implemented in this way? Why linker does not assume that later some object file may need pthread_create?Revisal
@Revisal This is a question answering site, and asking questions is free :-) Please ask a new question as a real question, instead of continuing discussion in comments.Ionization
A
56

For Linux the correct command is:

gcc -o term term.c -lpthread
  1. you have to put -lpthread just after the compile command,this command will tell to the compiler to execute program with pthread.h library.
  2. gcc -l links with a library file.Link -l with library name without the lib prefix.
Agglutinate answered 16/4, 2019 at 10:1 Comment(2)
It's not a good idea to use a non-standard flag when a standard flag exists that has the same function on your platform.Transubstantiation
This worked for me ... other solutions didn'tFarlie
C
45

in eclipse

properties->c/c++Build->setting->GCC C++ linker->libraries in top part add "pthread"

Crisper answered 22/10, 2012 at 7:36 Comment(2)
Same tip applyes in code::project (and I think others IDE too)Oar
I know this might be a little late, but. If you cannot find the C/C++ Build setting in the properties (I couldn't, maybe it's by installation or a bug), then there is a direct lower level workaround using the CMakeLists.txt file. You need to insert SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread") before the add_executable command. This will instruct the linker to do the same (see CMAKE_EXE_LINKER_FLAGS and SET documentation for more help).Gilleod
V
36

Running from the Linux terminal, what worked for me was compiling using the following command (suppose the c file I want to compile is called test.c):

gcc -o test test.c -pthread

Hope it helps somebody!

Varitype answered 30/9, 2018 at 2:36 Comment(1)
confirmed in Ubuntu 16.xGradient
B
33

If you are using cmake, you can use:

add_compile_options(-pthread)

Or

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
Borosilicate answered 7/8, 2018 at 3:47 Comment(0)
J
30

I believe the proper way of adding pthread in CMake is with the following

find_package (Threads REQUIRED)

target_link_libraries(helloworld
    ${CMAKE_THREAD_LIBS_INIT}
)
Jiujitsu answered 28/8, 2019 at 5:59 Comment(1)
This has the same effect but used the Threads::Threads target rather than the CMAKE_THREAD_LIBS_INIT variable. target_link_libraries(helloworld PUBLIC Threads::Threads) Lenhart
F
20

Acutally, it gives several examples of compile commands used for pthreads codes are listed in the table below, if you continue reading the following tutorial:

https://computing.llnl.gov/tutorials/pthreads/#Compiling

enter image description here

Formation answered 28/1, 2014 at 6:33 Comment(0)
R
11

Compile it like this : gcc demo.c -o demo -pthread

Radiosensitive answered 14/2, 2017 at 11:40 Comment(0)
I
8

In Visual Studio 2019 specify -pthread in the property pages for the project under:

Linker -> Command Line -> Additional Options

Type in -pthread in the textbox.

Igbo answered 19/5, 2019 at 3:9 Comment(2)
When I do that, I get the error "pthread: No such file or directory"Bechuanaland
My link was failing in a Release build but succeeding in the Debug build. It turns out that the -pthread was missing from the Release build. Make sure both build environments match.Parrotfish
P
4

You need to use the option -lpthread with gcc.

Peripheral answered 11/3, 2012 at 23:33 Comment(2)
wrong information! -lpthread is not an "option", it specifies a library.Zelaya
a command line option (in contrast to a command line argument)Tallowy
C
4

you need only Add "pthread" in proprieties=>C/C++ build=>GCC C++ Linker=>Libraries=> top part "Libraries(-l)". thats it

Crisper answered 7/4, 2012 at 5:16 Comment(0)
F
4

check man page and you will get.

Compile and link with -pthread.

SYNOPSIS
       #include <pthread.h>

       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);


       Compile and link with -pthread.
       ....
Febricity answered 16/5, 2019 at 12:42 Comment(0)
T
4

Since none of the answers exactly covered my need (using MSVS Code), I add here my experience with this IDE and CMAKE build tools too.

Step 1: Make sure in your .cpp, (or .hpp if needed) you have included:

#include <functional>

Step 2 For MSVSCode IDE users: Add this line to your c_cpp_properties.json file:

"compilerArgs": ["-pthread"],

Add this line to your c_cpp_properties.json file

Step 2 For CMAKE build tools users: Add this line to your CMakeLists.txt

set(CMAKE_CXX_FLAGS "-pthread")

Note: Adding flag -lpthread (instead of -pthread) results in failed linking.

Tormentil answered 1/2, 2021 at 17:17 Comment(0)
R
2

From man gcc,

  -pthread
       Define additional macros required for using the POSIX threads library.
       You should use this option consistently for both compilation and linking.
       This option is supported on GNU/Linux targets, 
           most other Unix derivatives, 
           and also on x86 Cygwin and MinGW targets.

It is correct that -pthread is an option and the best way to handle this. There are statements in some answers that it generates different compiled code. This is misleading.

If you wish to duplicate -pthread, you could use -lpthread -D_REENTRANT=1. So there are two things going on with the -pthread option.

Indeed it links with the pthread library as many answers express. Also, the order of the pthread library is important because it may override some weak symbols. So a correct version using -lpthread may need to have it multiple times on the command line.

The other important part is the _REENTRANT define. Note, that this is in the implementation namespace. Some people may care for portability and other not. However, it is very important that it is defined as the first thing in the compilation unit. This symbol will alter the way that many system headers files are parsed.

You can include #define _REENTRANT 1 at the top of every source file, but it is much easier to have it on the command line. Again, the -pthread is the best way to achieve this. Also, gcc may change the way this is implemented in the future. However, I think it is important for programmers to understand what is going on.


term.c: In function ‘main’: term.c:23: warning: incompatible implicit declaration of built-in function ‘exit’

You never included <stdlib.h>, where exit() is declared. Also, I think newer versions of gcc have removed the need for _REENTRANT.

So, it is NOT generating different code. Ie, the backend of the compiler is NOT different. It is only conditional compilation and linking to different libraries. It does not generate 'lock free' code or add appropriate machine barriers because you have used this option.

Reticle answered 3/4, 2022 at 21:22 Comment(1)
_REENTRANT is an example that was used with some GCC versions. Newer standards, etc may change the structure that is used to alter they system/compiler headers depending on what language version, OS and C library is used.Reticle
I
0

In Anjuta, go to the Build menu, then Configure Project. In the Configure Options box, add:

LDFLAGS='-lpthread'

Hope it'll help somebody too...

Incurrence answered 26/1, 2013 at 14:46 Comment(0)
H
0

Sometimes, if you use multiple library, check the library dependency. (e.g. -lpthread -lSDL... <==> ... -lSDL -lpthread)

Hutcherson answered 3/7, 2013 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.