pthreads, part of the POSIX standard rather than the C language standard itself, provides pthread_create for starting a new thread, pthread_join for waiting on one to finish, and pthread_mutex_t for protecting shared data from simultaneous access. C11 introduced its own optional threads.h with a similar but distinctly-named API (thrd_create, mtx_t), intended to bring threading properly into the C standard — but adoption has been inconsistent enough across major compilers that pthreads has remained the practical, near-universal default for real C concurrency code.
Creating and joining a thread
pthread_join blocks the calling thread until the specified thread finishes — without it, main() might exit before the spawned thread ever runs, terminating the whole process along with it.
#include <pthread.h>
void *printMessage(void *arg) {
printf("Hello from a thread\n");
return NULL;
}
int main(void) {
pthread_t thread;
pthread_create(&thread, NULL, printMessage, NULL);
pthread_join(thread, NULL); // wait for the thread to finish before continuing
return 0;
}
// compile with: gcc -pthread program.cMutexes: protecting shared data
Without the mutex, two threads incrementing counter simultaneously can genuinely lose an update — a real data race, not just a theoretical concern — since counter++ is not a single atomic operation at the machine level.
#include <pthread.h>
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
void *increment(void *arg) {
for (int i = 0; i < 100000; i++) {
pthread_mutex_lock(&lock);
counter++; // protected — only one thread at a time can be here
pthread_mutex_unlock(&lock);
}
return NULL;
}threads.h: standardized in C11, rarely used in practice
The API is conceptually similar to pthreads but with different names — thrd_create instead of pthread_create, mtx_t instead of pthread_mutex_t — yet real-world code overwhelmingly still reaches for pthreads, since C11's threading support is optional (a conforming compiler doesn't have to implement it) and support has genuinely varied.
#include <threads.h> // C11's standard threading header — optional, uneven support
int myThread(void *arg) {
printf("Hello from a C11 thread\n");
return 0;
}
thrd_t t;
thrd_create(&t, myThread, NULL);
thrd_join(t, NULL);