Multithreading with pthreads
Build multithreaded C programs — pthreads, synchronization primitives, thread safety, and concurrent data structures.
55 min•By Priygop Team•Last updated: Feb 2026
POSIX Threads (pthreads)
- Thread Creation: pthread_create(&thread, NULL, function, arg) — creates a new thread executing function(arg). Returns 0 on success
- Thread Joining: pthread_join(thread, &result) — blocks until thread finishes. Retrieves return value. Always join or detach every thread to avoid resource leaks
- Thread Detachment: pthread_detach(thread) — thread resources are automatically freed on completion. Use when you don't need the return value
- Mutex Locks: pthread_mutex_lock/unlock — mutual exclusion for shared data. Only one thread can hold the lock at a time. Always lock/unlock in the same order to prevent deadlocks
- Condition Variables: pthread_cond_wait/signal — threads wait for a condition to become true. Used in producer-consumer pattern. Always use with a mutex and a while loop (spurious wakeups)
- Read-Write Locks: pthread_rwlock — multiple readers OR one writer. Better performance when reads >> writes. Use for shared data structures like caches
Thread Safety Patterns
- Race Condition: Two threads accessing shared data without synchronization — the result depends on timing. Use mutexes to protect shared state
- Deadlock: Thread A holds lock 1 and waits for lock 2. Thread B holds lock 2 and waits for lock 1. Neither can proceed. Prevention: always acquire locks in the same order
- Producer-Consumer: Producer thread adds items to a shared buffer, consumer thread removes them. Use mutex + condition variables. Bounded buffer prevents memory exhaustion
- Thread Pool: Pre-create N worker threads that process tasks from a queue. Avoids thread creation overhead per task. Used in web servers, database connection pools
- Thread-Local Storage: pthread_key_create/pthread_setspecific — per-thread data without sharing. errno is thread-local in modern systems. Use for thread-specific caches
- Atomic Operations: __atomic_add_fetch, __atomic_compare_exchange — lock-free operations for simple counters and flags. Much faster than mutexes for simple operations