What it is
pthread (POSIX Threads) is a standard C library for creating and managing threads. It provides APIs for multithreading, synchronization, and concurrency control in C programs on POSIX-compliant systems.
pthread allows creating multiple threads, synchronizing access to shared resources with mutexes and condition variables, and coordinating execution using thread joins or detachment.
Installation
Usually included in glibc; link with -pthread during compilationGetting started
The smallest useful thing you can do with it, and what each part means.
#include <pthread.h>
#include <stdio.h>
void* print_message(void* arg) {
printf("Hello from thread!\n");
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, print_message, NULL);
pthread_join(thread, NULL);
return 0;
}#include <pthread.h>
#include <stdio.h>
int counter = 0;
pthread_mutex_t lock;
void* increment(void* arg) {
pthread_mutex_lock(&lock);
counter++;
pthread_mutex_unlock(&lock);
return NULL;
}
int main() {
pthread_t threads[10];
pthread_mutex_init(&lock, NULL);
for(int i = 0; i < 10; i++) pthread_create(&threads[i], NULL, increment, NULL);
for(int i = 0; i < 10; i++) pthread_join(threads[i], NULL);
printf("Counter: %d\n", counter);
pthread_mutex_destroy(&lock);
return 0;
}Advanced usage
Where the library earns its place over a simpler alternative.
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t lock;
pthread_cond_t cond;
int ready = 0;
void* wait_thread(void* arg) {
pthread_mutex_lock(&lock);
while (!ready) pthread_cond_wait(&cond, &lock);
printf("Condition met!\n");
pthread_mutex_unlock(&lock);
return NULL;
}
void* signal_thread(void* arg) {
pthread_mutex_lock(&lock);
ready = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_mutex_init(&lock, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&t1, NULL, wait_thread, NULL);
pthread_create(&t2, NULL, signal_thread, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);
return 0;
}#include <pthread.h>
#include <stdio.h>
pthread_key_t key;
void destructor(void* value) { printf("Thread-specific data freed\n"); }
void* thread_func(void* arg) {
pthread_setspecific(key, arg);
printf("Thread data: %s\n", (char*)pthread_getspecific(key));
return NULL;
}
int main() {
pthread_key_create(&key, destructor);
pthread_t thread;
char* msg = "Hello Thread";
pthread_create(&thread, NULL, thread_func, msg);
pthread_join(thread, NULL);
pthread_key_delete(key);
return 0;
}Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- EDEADLK
- Occurs when a deadlock is detected. Ensure consistent locking order or use `pthread_mutex_trylock`.
- EINVAL
- Indicates invalid arguments passed to pthread functions. Verify thread, mutex, and condition variable initialization.
- ENOMEM
- Insufficient memory to create a new thread. Consider limiting thread creation or using a thread pool.
Best practices
- Always initialize and destroy mutexes and condition variables properly.
- Avoid deadlocks by locking mutexes in a consistent order.
- Use `pthread_join` or detach threads to manage their lifecycle.
- Minimize the work done while holding a mutex to reduce contention.
- Prefer thread-local storage for data specific to a thread.
Background
Why it exists, and what it was reacting to.
pthread was developed as part of the POSIX standard to allow portable multithreaded programming in C. It provides primitives for thread creation, joining, mutexes, condition variables, and thread-local storage, enabling developers to write efficient concurrent programs.
