POSIX Threads vs C11 Threads: Key Differences
This article examines the core distinctions between POSIX Threads
(pthreads) and the native C standard threads library
(threads.h) introduced in C11. While both libraries provide
multithreading capabilities for C programmers, they differ significantly
in their standardization history, platform portability, API design, and
overall feature completeness. Understanding these differences allows
developers to choose the right threading model for their target
environments and application requirements.
Standardization and History
POSIX Threads, defined by IEEE POSIX 1003.1c in 1995, were developed as an operating system-level standard for Unix-like systems. Because of their early adoption, pthreads became the de facto standard for multithreading in C and C++ for decades.
In contrast, the ISO C standard did not include a native
multithreading model until C11 (ISO/IEC 9899:2011), which introduced
<threads.h>. This addition provided the language
itself with a formalized memory model and native thread primitives,
eliminating the necessity to rely on external platform standards for
basic concurrency.
Portability and Compiler Support
Portability represents one of the largest practical differences between the two models:
- POSIX Threads: Pthreads are ubiquitous across
Linux, macOS, BSD, and other Unix derivatives. On Microsoft Windows,
pthreads are not natively supported and require third-party translation
layers such as
pthreads4wor POSIX environments like Cygwin and MSYS2. - C11 Threads: Because they are defined by the ISO C
standard, native threads are intended to work across any platform with a
conforming C11 implementation, including Windows. However, C11 made
multithreading an optional feature (indicated by the
__STDC_NO_THREADS__macro). Support in mainstream compilers lagged for years; while glibc and Microsoft Visual Studio (MSVC) now support<threads.h>, Appleās macOS standard C library still lacks full native implementation out of the box.
Feature Set and Capabilities
The feature breadth of POSIX threads far exceeds that of the C11 thread specification:
- Thread Management: Pthreads offer granular control
via attribute objects (
pthread_attr_t), enabling developers to set stack size, scheduling policies, and thread detach states before creation. C11'sthrd_createaccepts only the function pointer and an argument, providing no mechanism to configure attributes directly. - Synchronization Primitives: Pthreads include
standard mutexes, condition variables, read-write locks
(
pthread_rwlock_t), barriers (pthread_barrier_t), and spinlocks. C11 native threads define only basic mutexes (mtx_t) and condition variables (cnd_t), omitting read-write locks and barriers entirely. - Thread Cancellation: Pthreads support explicit
thread cancellation (
pthread_cancel), allowing one thread to terminate another with clean-up handlers. C11 lacks a cancellation mechanism; threads must instead poll flags or atomic variables to terminate cooperatively. - Thread-Specific Storage (TSS): Both models support
thread-local storage, but pthreads (
pthread_key_create) provide built-in destructor callbacks that run automatically when a thread exits. C11'stss_createalso supports destructors, though general thread-local storage is often handled via the simpler_Thread_localstorage duration specifier introduced in the same standard.
API Design and Naming Conventions
The two interfaces follow similar structural patterns but differ in syntax and error reporting:
| Feature | POSIX Threads
(pthread.h) |
C11 Native Threads
(threads.h) |
|---|---|---|
| Thread Type | pthread_t |
thrd_t |
| Thread Creation | pthread_create() |
thrd_create() |
| Mutex Type | pthread_mutex_t |
mtx_t |
| Condition Variable | pthread_cond_t |
cnd_t |
| Thread Exit | pthread_exit() |
thrd_exit() |
Pthreads functions typically return an integer where 0
indicates success and any non-zero value represents a specific POSIX
error code (such as EINVAL or EBUSY). C11
native threads instead return standardized enumeration values such as
thrd_success, thrd_error,
thrd_busy, thrd_nomem, and
thrd_timedout.
Choosing Between Pthreads and C11 Threads
Pthreads remain the preferred choice for software tightly coupled to POSIX systems, high-performance computing requiring fine-grained thread scheduling, or applications that need advanced primitives like read-write locks.
C11 native threads are suitable for cross-platform libraries and applications that require straightforward thread execution, basic mutual exclusion, and independence from Unix-centric runtime dependencies.