How to Fix an “Undefined Reference to Pthread Create” in Linux

I remember the first time I worked with POSIX threads in C everything was going well until I hit a wall with one strange error in inux:

undefined reference to `pthread_create`

At first, I thought, “Wait, I already included <pthread.h>, so why is the compiler acting like it’s never heard of pthread_create
Turns out, this is one of those classic Linux gotchas. Let me walk you through what happened, how I fixed it a linux, and how I turned it into a little learning project.

The Demo Code

Here’s the code I was testing:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h> // Needed for exit()

#define NUM_THREADS 5

void *PrintHello(void *threadid)
{
long 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);
}

The Error

When I compiled it like this:

gcc -o term term.c

I got this:

/tmp/cc8BMzwx.o: In function `main':
term.c:(.text+0x82): undefined reference to `pthread_create'
collect2: ld returned 1 exit status

Why This Happen

This isn’t because pthread.h is missing the compiler sees the function declaration just fine.
The problem is linking.

pthread_create isn’t in the default C library (libc).
It lives in the POSIX threads library (libpthread). If you don’t tell the compiler to link it, you’ll get this linux“undefined reference” error at the linking stage.

The Fix

You just need to link with libpthread.

You can do this in two ways:

gcc -o term term.c -pthread   # Recommended

or:

gcc -o term term.c -lpthread

I recommend -pthread because it not only links the library but also sets compiler flags to ensure thread-safe code.

After that, the program runs perfectly.

Extra Practice:

The original code calls pthread_exit(NULL) in main() to let threads finish, but that’s not always the cleanest way. I wanted to practice joining threads explicitly and passing them custom data.

Here’s the improved version:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define NUM_THREADS 5

struct thread_data {
long thread_id;
const char *message;
};

void *PrintMessage(void *threadarg)
{
struct thread_data *data;
data = (struct thread_data *) threadarg;
printf("Thread #%ld: %s\n", data->thread_id, data->message);
pthread_exit(NULL);
}

int main()
{
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int rc;

for (long t = 0; t < NUM_THREADS; t++) {
td[t].thread_id = t;
td[t].message = "Hello from my practice thread!";
printf("Main: creating thread %ld\n", t);

rc = pthread_create(&threads[t], NULL, PrintMessage, (void *)&td[t]);
if (rc) {
fprintf(stderr, "Error: pthread_create() returned %d\n", rc);
exit(EXIT_FAILURE);
}
}

for (long t = 0; t < NUM_THREADS; t++) {
pthread_join(threads[t], NULL);
}

printf("Main: All threads finished. Exiting.\n");
return 0;
}

Example Output

Main: creating thread 0
Main: creating thread 1
Main: creating thread 2
Main: creating thread 3
Main: creating thread 4
Thread #0: Hello from my practice thread!
Thread #1: Hello from my practice thread!
Thread #2: Hello from my practice thread!
Thread #3: Hello from my practice thread!
Thread #4: Hello from my practice thread!
Main: All threads finished. Exiting.

Final Thought

The “undefined reference to pthread_create” error looks intimidating the first time, but it’s just a linking problem. Once you know about -pthread, you can avoid it entirely.
For me, this turned into a great excuse to deepen my understanding of POSIX threads, argument passing, and thread synchronization.

Related blog posts