Fact-checked by Grok 2 weeks ago

pthreads

Pthreads, formally known as , is a standardized defined by the IEEE for creating and managing multiple threads of execution within a single process on POSIX-compliant operating systems, enabling efficient parallelism and concurrency in and C++ programs. This interface supports access among threads while providing mechanisms for to prevent race conditions and ensure . As part of the POSIX.1 standard, pthreads promotes portability across systems, including , , and macOS, by specifying over 100 functions for thread lifecycle management, scheduling, and inter-thread communication. The pthreads standard originated as an extension in IEEE Std 1003.1c-1995, which introduced the core threading model to address the growing need for multithreaded programming amid advancing multiprocessor hardware in the early 1990s. It was subsequently integrated into the base POSIX.1-2001 standard (IEEE Std 1003.1-2001), enhancing the overall POSIX framework for operating system interfaces and ensuring backward compatibility with earlier revisions. Implementations vary by system—such as the Native POSIX Thread Library (NPTL) on modern Linux kernels since 2003—but all conform to the POSIX requirements for thread-safe operations, with exceptions for a limited set of non-thread-safe functions like asctime() and getpwuid(). Key components of pthreads include and termination via functions like pthread_create() and pthread_join(), attribute for scheduling policies (e.g., SCHED_FIFO for ), and primitives such as mutex locks (pthread_mutex_lock()), variables (pthread_cond_wait()), and read-write locks for optimized concurrent access. Additional features support cancellation points for graceful thread termination, signal handling with per-thread masks (pthread_sigmask()), and two-level scheduling models (process-contention and system-contention scopes) to balance performance in multiprocessor environments. These elements make pthreads a foundational tool for , server applications, and systems, with ongoing relevance in modern despite the rise of higher-level concurrency models.

Overview

Definition and Purpose

pthreads, or Threads, is a standard specification for a set of library functions that enable the creation and management of threads within a process. It is defined in the pthread.h header file and typically implemented by the libpthread library, providing a portable for multithreaded programming on POSIX-compliant systems. The primary purpose of pthreads is to support multiple flows of control, known as threads, operating concurrently within a single process, where threads share a common and resources such as code segments, data, and open files. This shared model allows for efficient data exchange via memory, reducing the overhead associated with and enabling parallelism to enhance application responsiveness, throughput, and resource utilization on multi-core systems. Threads in pthreads are compared to full processes, as they incur lower and context-switching costs by avoiding the need for separate spaces. However, the shared access to resources requires primitives to prevent conditions and maintain . The execution model centers on a main that spawns and coordinates additional worker threads, all running concurrently to computational tasks.

Standards and Compliance

The POSIX Threads (pthreads) API originated as the threads extensions defined in IEEE Std 1003.1c-1995, also known as .1c-1995, which established the foundational interfaces for creating and managing threads in -compliant systems. This standard specified a set of C language functions for multithreaded programming, emphasizing portability across environments. In 2001, these extensions were integrated into the core .1 standard as IEEE Std 1003.1-2001, making threads a mandatory component for full conformance rather than an optional add-on. Subsequent revisions enhanced pthreads with capabilities. The POSIX.1-2008 standard (IEEE Std 1003.1-2008) incorporated additional extensions, building on earlier POSIX.1b provisions for scheduling and timers to support time-sensitive thread operations, such as priority-based scheduling policies. Conformance to these standards is determined through defined feature options and levels; for instance, _POSIX_THREADS indicates basic thread support, while _POSIX_THREAD_SAFE_FUNCTIONS requires thread-safe implementations of functions to prevent race conditions in multithreaded applications. Systems achieving POSIX conformance must support these options and pass rigorous testing, ensuring reliable behavior across compliant platforms. Compliance verification involves conformance tests administered by organizations like The Open Group, which certify systems against the standards. -compliant operating systems, such as distributions and BSD variants, implement pthreads to meet these requirements, enabling portable multithreaded code without vendor-specific adaptations. Pthreads also interact with related standards like .1b (IEEE Std 1003.1b-1993), which provides real-time scheduling mechanisms—such as and policies—that threads can inherit or set explicitly for predictable execution in time-constrained environments. As an alternative to pthreads, the standard (ISO/IEC 9899:2011) introduces a native threading via the <threads.h> header, offering basic creation, , and mutex operations standardized directly in the for broader portability beyond systems. However, on platforms, C11 threads are frequently implemented atop pthreads, inheriting its underlying mechanisms while providing a simpler, non--dependent interface. The Open Group's (), particularly versions aligned with POSIX.1-2001 and later, mandates pthreads support as part of its branding for certified Unix systems, promoting source-level portability and across diverse hardware and software ecosystems. This certification process ensures that applications using pthreads can run consistently on compliant systems, reducing development overhead for multithreaded software.

History

Origins and Development

In the early , the development of POSIX threads (pthreads) arose from the increasing prevalence of multi-processor hardware, which demanded efficient mechanisms for parallelism and concurrency at the application level within Unix systems. This need was amplified by fragmented threading implementations across Unix variants, prompting a push for portability to facilitate and deployment on diverse platforms. in concurrency models, including processes and user-level threading, further influenced the drive toward a standardized that could hardware-specific details while supporting scalable multithreading. The primary contributors to pthreads' origins were members of the IEEE Portable Applications Standards Committee (PASC), a under the IEEE that coordinated the standards effort. This group drew inspiration from pioneering threading systems, notably the C threads library developed at as part of the operating system project, which emphasized user-level management for performance, and Sun Microsystems' lightweight processes (LWPs), which integrated kernel support for threads to handle efficiently. These influences helped shape a unified model that balanced portability with low-overhead execution. Initial proposals for the pthreads specification emerged through iterative drafts circulated by the PASC working group in and 1994, targeting essential features like thread creation, , and cross-platform compatibility among Unix implementations. These drafts aimed to resolve inconsistencies in vendor-specific threading APIs by defining a minimal, extensible suitable for both - and kernel-level use. To validate and iterate on these concepts prior to formalization, pre-standard libraries were developed, including the pthreads prototype released in , a user-space implementation that tested core primitives on Unix systems without modifications.

Standardization and Evolution

The pthreads API was formally adopted as a standalone standard in POSIX.1c-1995, designated as IEEE Std 1003.1c-1995, providing the foundational threading extensions for POSIX-compliant systems. This initial specification defined core thread management, synchronization primitives, and related interfaces, enabling portable multithreaded programming across UNIX-like operating systems. In 2001, the pthreads functionality was merged into the base POSIX.1 standard as part of IEEE Std 1003.1-2001, consolidating it with other system interfaces to streamline conformance and adoption. Subsequent revisions under the Austin Group's oversight introduced enhancements to address evolving needs in concurrency and . The 2008 revision (IEEE Std 1003.1-2008) incorporated extensions from POSIX.1b-1993, adding features such as barriers for , spinlocks for low-latency locking in multiprocessor environments, and robust mutexes to owner death scenarios gracefully. The 2016 edition (IEEE Std 1003.1-2016) primarily applied corrigenda to the 2008 standard with minor clarifications. The 2024 edition (IEEE Std 1003.1-2024, published June 2024) aligned with the language standard for improved memory model consistency and integrated with broader POSIX capabilities, without major new pthreads features. These changes, driven by the Austin Group's collaborative efforts involving IEEE, ISO/IEC, and industry stakeholders, also maintained alignment with the ISO/IEC 9945, with pthreads included since the 1996 edition and updated in subsequent versions (e.g., 2003, 2017). As of November 2025, the pthreads specification remains stable within IEEE Std 1003.1-2024, with ongoing minor amendments through the Austin Group to maintain relevance amid advancing hardware and software paradigms. This version continues to influence the ISO/IEC 9945, ensuring pthreads' portability and interoperability in diverse computing ecosystems.

Core Concepts

Threads versus Processes

In systems, a is defined as an addressable set of resources consisting of a memory , executable program, , and open files, serving as an independent . are created using mechanisms like fork() followed by exec(), which involve significant overhead due to the need to allocate and initialize a separate , often through techniques to duplicate the parent's memory. This separation ensures isolation but makes processes heavier in terms of resource consumption and startup time compared to lighter execution units. In contrast, POSIX threads, or pthreads, represent lightweight units of execution known as a single flow of control within a , allowing multiple threads to operate concurrently under the same process umbrella. Threads share the process's code, , , open files, signals, and other global resources, but each maintains private elements such as its own , registers, thread ID, errno value, signal mask, and scheduling attributes. This shared-yet-private model enables efficient resource utilization, as threads are spawned via pthread_create() without duplicating the entire , resulting in lower creation and context-switching costs. POSIX distinguishes processes and threads through specific identifiers and communication paradigms: processes are identified by a pid_t type process ID unique system-wide, while threads use a pthread_t type ID that is unique only within their process. Inter-process communication relies on mechanisms like , message queues, or semaphores for data exchange across isolated address spaces, whereas threads communicate directly via , simplifying data access but necessitating careful to prevent race conditions. The use of threads in pthreads offers advantages such as faster context switching due to shared resources and easier without IPC overhead, making them suitable for concurrent tasks within a single application. However, this proximity introduces complexity, as threads must employ primitives like mutexes to manage shared access, unlike the inherent isolation of processes that reduces such risks.

Thread Lifecycle and States

In POSIX threads (pthreads), a thread progresses through several conceptual states during its lifecycle, reflecting its readiness to execute, active execution, suspension, and completion. These states include new, runnable, running, blocked, and terminated, which align with the underlying operating system scheduler's management of thread execution. Upon creation, a thread enters the new state immediately after the pthread_create() call succeeds, where it is initialized but not yet scheduled for execution. From the new state, the thread transitions to the runnable state, becoming eligible for scheduling by the system kernel, which decides when to allocate based on priorities and policies. Once in the runnable state, the thread moves to the running state when the scheduler assigns it to a CPU core, allowing it to actively execute its start routine and associated code. A running thread may transition to the blocked state when it encounters a synchronization , such as waiting on a mutex or condition variable, or performs blocking I/O operations, suspending its execution until the required or event becomes available. Upon resolution of the blocking condition—such as acquiring a lock or receiving a signal—the thread returns to the runnable state, ready for rescheduling. The thread reaches the terminated state through normal completion by returning from its start routine (implicitly calling pthread_exit()), explicit invocation of pthread_exit(), or cancellation via another thread, at which point its execution context is no longer active. Throughout its lifecycle, a pthread manages resources independently from other threads within the same , including stack allocation and signal handling. Each thread receives its own private , with a minimum size defined by the system constant PTHREAD_STACK_MIN, to store local variables and function call frames without interfering with other threads; the stack size can be customized during to accommodate specific workload needs. Signal handling is also per-thread: each thread maintains its own signal mask, inherited from the creating thread, allowing individual control over which signals are blocked or delivered, while process-wide signal dispositions remain shared across all threads. The distinction between joinable and detached threads significantly affects resource reclamation upon termination. By default, threads are created in the joinable state, where their resources—such as thread ID, stack, and thread-specific data—persist after termination until another thread explicitly calls pthread_join() to retrieve the and reclaim them, preventing resource leaks in long-running applications. In contrast, a detached thread, set via attributes at creation or by calling pthread_detach() post-creation, automatically reclaims all its resources immediately upon entering the terminated state, simplifying cleanup but forgoing the ability to retrieve an exit status. This choice impacts and program design, as unreclaimed joinable threads can accumulate and exhaust system resources if not properly joined.

Thread Management

Creating and Initializing Threads

In POSIX-compliant systems, are created using the pthread_create , which initiates a new of execution within the current . This allows for the specification of thread attributes, a starting routine, and an argument to pass to that routine. The main of a is implicitly created by the operating system upon startup, whereas additional worker must be explicitly created using this . The function signature is as follows:
c
#include <pthread.h>

int pthread_create(pthread_t *restrict thread,
                   const pthread_attr_t *restrict attr,
                   void *(*start_routine)(void *),
                   void *restrict arg);
Upon successful invocation, pthread_create stores a unique thread identifier in the location pointed to by thread, which remains valid and distinct from other thread IDs within the same process until all references to it are destroyed. The new thread begins execution at the address specified by start_routine, with arg passed as its single argument; if start_routine returns, the thread implicitly calls pthread_exit with that return value. The attr parameter points to a thread attribute object (or NULL for default attributes), which can influence aspects such as stack size or detach state, though detailed attribute configuration is handled separately. To pass multiple parameters to start_routine, developers typically encapsulate them in a structure and cast its address to void * for the arg parameter. The function returns 0 on success; otherwise, it returns an error number without setting errno, and the contents of *thread are undefined. Common errors include EAGAIN, indicating insufficient resources to create another or that the limit {PTHREAD_THREADS_MAX} has been exceeded, and EINVAL, signaling invalid settings in the attr object (though EINVAL support for attr is optional in the standard). Another possible error is EPERM, if the caller lacks permission to set the scheduling or parameters specified in attr. identifiers are guaranteed to be unique within a , facilitating identification for subsequent operations like joining or cancellation. Best practices for using pthread_create emphasize robust error handling and . Applications should always check value immediately after the call to detect failures and avoid proceeding with invalid thread IDs. To prevent race conditions during global initialization shared among threads, it is advisable to perform such setup in the main thread before creating workers or use synchronization primitives like mutexes for protected access. Additionally, initializing any necessary thread attributes with pthread_attr_init prior to creation ensures predictable behavior, and threads should be designed to be joinable by default to allow proper resource reclamation.

Terminating, Joining, and Detaching Threads

In threads (pthreads), thread termination occurs either explicitly through the pthread_exit() function or implicitly upon return from the thread's start routine. The pthread_exit(void *value_ptr) function terminates the calling thread and makes the value pointed to by value_ptr available to any thread that subsequently joins with it. This function first executes any registered cancellation cleanup handlers in reverse order of registration and then invokes thread-specific data destructors for keys with non-NULL destructors, but it does not release process-wide resources such as locked mutexes or open file descriptors, nor does it invoke atexit() handlers. If a thread returns from its start routine (the function passed to pthread_create()), this implicitly calls pthread_exit() with the return value as the exit status. When the last thread in a process terminates, the entire process exits with a status of 0, equivalent to calling exit(0). The pthread_exit() function does not return to its caller and has no defined errors. To manage thread completion and retrieve results, the pthread_join(pthread_t thread, void **value_ptr) function allows a calling to wait for the specified to terminate. Upon successful termination of the target , pthread_join() suspends the caller until the event occurs, then stores the termination value (from pthread_exit() or the start routine's return) in the location pointed to by value_ptr if it is not , and marks the target as terminated. It returns 0 on success; otherwise, it returns an error number without setting errno. Common errors include ESRCH if the thread ID is invalid (e.g., after the thread's lifetime has ended), EINVAL if the thread is not joinable, and EDEADLK if a condition is detected, such as attempting to join the calling thread itself. Behavior is undefined if multiple threads attempt to join the same target simultaneously or if the target is already detached. For threads that do not require result retrieval, detaching via pthread_detach(pthread_t thread) enables automatic reclamation of the thread's resources upon termination without needing a join. This function marks the specified as detached, ensuring that its storage is freed when it terminates, and returns 0 on success or an number otherwise; it does not terminate a running thread and has no EINTR error. Once detached, a thread cannot be joined, and attempting to do so results in . Implementations may return ESRCH for an invalid thread ID or EINVAL if the thread is already detached or not joinable, though the standard defines these as optional for certain cases. Proper handling of termination through joining or detaching is essential to prevent resource leaks, as joinable threads that neither join nor detach retain their storage until explicitly reclaimed, potentially leading to memory exhaustion in long-running applications with many threads. For example, in a multi-threaded , failing to join worker s after task completion could accumulate unreclaimed thread descriptors, whereas detaching them allows immediate cleanup post-termination.

Synchronization

Mutexes and Locking Mechanisms

In POSIX threads (pthreads), mutexes are synchronization primitives used to protect shared data from concurrent access by multiple threads, ensuring . The pthread_mutex_t type represents a mutex object, which can be in one of two states: unlocked or locked by a single thread. Mutexes are essential for preventing conditions in multithreaded programs. Mutexes are initialized either statically at using the macro PTHREAD_MUTEX_INITIALIZER, which sets default attributes, or dynamically at runtime with the pthread_mutex_init function:
c
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
This function returns 0 on success or an error code such as ENOMEM if allocation fails or EPERM if the process lacks permission. The attr allows customization of mutex properties; if NULL, default attributes (typically equivalent to a normal mutex) are used. After use, mutexes should be destroyed with pthread_mutex_destroy to free resources. To acquire a mutex, a thread calls pthread_mutex_lock, which blocks the calling thread until the mutex is available and then locks it, making the caller the owner:
c
int pthread_mutex_lock(pthread_mutex_t *mutex);
If the mutex is already locked, the thread waits. To release the lock, the owning thread must call pthread_mutex_unlock:
c
int pthread_mutex_unlock(pthread_mutex_t *mutex);
Unlocking by a non-owner returns EPERM. For non-blocking attempts, pthread_mutex_trylock returns immediately: 0 if locked successfully, or EBUSY if already locked by another thread. These functions support various mutex types defined by , set via the pthread_mutexattr_settype function with attributes like PTHREAD_MUTEX_NORMAL (basic type with no error checking; relocking causes , potentially ), PTHREAD_MUTEX_RECURSIVE (permits the same thread to relock multiple times, requiring equal unlocks), and PTHREAD_MUTEX_ERRORCHECK (returns errors like EDEADLK for recursive locking attempts or unlocking by non-owners). The default type is often PTHREAD_MUTEX_DEFAULT, which behaves like normal but may vary by implementation. Robust mutexes, enabled by setting the robustness attribute to PTHREAD_MUTEX_ROBUST via pthread_mutexattr_setrobust, provide recovery from scenarios where the owning terminates unexpectedly without unlocking. In such cases, the next pthread_mutex_lock or pthread_mutex_trylock call succeeds but returns EOWNERDEAD, indicating the mutex state may be inconsistent; the new owner must then call pthread_mutex_consistent to restore usability before unlocking or further operations. Failure to do so renders the mutex permanently unusable (returning ENOTRECOVERABLE on future attempts), requiring destruction and reinitialization. The default robustness is PTHREAD_MUTEX_STALLED, where owner death leaves the mutex locked indefinitely, potentially causing deadlocks. Deadlocks, where threads wait indefinitely for each other's locks, can be prevented by enforcing a consistent global ordering when acquiring multiple mutexes (e.g., always locking lower-address mutexes first to avoid circular waits). Additionally, pthread_mutex_timedlock allows specifying an absolute timeout via a struct timespec, returning ETIMEDOUT if the lock cannot be acquired before the deadline, enabling timeout-based avoidance of indefinite waits. Common errors include EDEADLK (detected in error-checking mutexes during lock acquisition) and EPERM (for unauthorized unlocks or operations).

Condition Variables and Signaling

Condition variables in threads (pthreads) provide a mechanism for threads to wait until a particular condition becomes true, enabling efficient coordination beyond . A condition variable is represented by the opaque type pthread_cond_t and is used to signal changes in state that other threads may be waiting for. Unlike mutexes, which only ensure exclusive access, condition variables allow threads to suspend execution until notified, reducing busy-waiting and improving performance in multithreaded applications. To initialize a condition variable, the pthread_cond_init function is called with a pointer to the pthread_cond_t object and optionally a pointer to attribute attributes of type pthread_condattr_t; if the attributes pointer is NULL, default attributes are used. The synopsis is int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);, returning 0 on success or an error code such as EINVAL if the attributes are invalid, ENOMEM if insufficient memory exists, or EBUSY if the system cannot support another condition variable. For static initialization without runtime checks, the macro PTHREAD_COND_INITIALIZER can be used, as in pthread_cond_t cond = PTHREAD_COND_INITIALIZER;. Reinitializing an already initialized condition variable leads to undefined behavior, and initialization must precede any use in wait or signal operations. The primary operation for waiting on a condition variable is pthread_cond_wait, which atomically releases the associated mutex (held by the calling thread) and blocks until the condition variable is signaled, after which it reacquires the mutex before returning. Its synopsis is int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);, and it returns 0 on success or errors like EINVAL if the condition variable or mutex is invalid or if the mutex is not owned by the calling thread. Condition variables must always be paired with a mutex to protect the shared being waited on, ensuring atomicity in checking the condition and updating state. Due to possible spurious wakeups—where a thread wakes without a corresponding signal—the waiting thread must re-evaluate the (e.g., a shared or counter) after reacquiring the mutex, typically in a like while (!predicate) { pthread_cond_wait(&cond, &mutex); }. This function is a cancellation point, meaning a thread can be asynchronously canceled during the wait, with the mutex reacquired before cleanup handlers run. For scenarios requiring a timeout, pthread_cond_timedwait extends this behavior by blocking until signaled or until an absolute time specified by a struct timespec *abstime elapses, whichever occurs first. Its synopsis is int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);, returning ETIMEDOUT if the timeout expires without a signal, in addition to other errors like EINVAL for an invalid time specification. The mutex is still reacquired upon return, even on timeout, and spurious wakeups necessitate the same predicate-checking loop as in the untimed wait. This allows threads to avoid indefinite blocking, useful in or responsive applications. To notify waiting threads, pthread_cond_signal wakes at least one thread blocked on the condition variable, if any are waiting; the woken thread then reacquires its mutex and proceeds. The synopsis is int pthread_cond_signal(pthread_cond_t *cond);, returning 0 on success or EINVAL if the condition variable is invalid. It has no effect if no threads are waiting and does not return EINTR on signal interruption. Calling pthread_cond_signal without holding the mutex is permitted but may lead to race conditions; holding the mutex ensures the signal follows a state change that makes the predicate true. For waking all waiting threads, pthread_cond_broadcast is used instead, with the synopsis int pthread_cond_broadcast(pthread_cond_t *cond); and the same return values and errors. The order of unblocking is determined by the system's scheduling policy, and like signal, it is most effective when called while holding the mutex after updating the shared state. Before destroying a condition variable with pthread_cond_destroy, ensure no threads are blocked on it to avoid . The synopsis is int pthread_cond_destroy(pthread_cond_t *cond);, returning 0 on success or EBUSY if threads are waiting or EINVAL if the object is invalid. After destruction, the condition variable becomes uninitialized and may be safely reinitialized, but attempting to destroy one in use by other threads results in unpredictable outcomes. Proper cleanup is essential for resource management in long-running programs.

Advanced Features

Thread Attributes and Scheduling

In POSIX threads (pthreads), thread attributes allow customization of thread properties prior to creation using the opaque object type pthread_attr_t. This object is initialized with the pthread_attr_init() function, which sets all attributes to their default values, and destroyed with pthread_attr_destroy() to release associated resources; both functions return 0 on success or an such as EINVAL if the argument is invalid. These attributes are passed to pthread_create() to configure the new thread, enabling behaviors distinct from system defaults without altering the thread after creation. One key attribute is the detach state, which determines whether a thread is joinable or detached. The default is PTHREAD_CREATE_JOINABLE, allowing other threads to wait for its termination using pthread_join() to reclaim resources; setting it to PTHREAD_CREATE_DETACHED via pthread_attr_setdetachstate() means the thread cannot be joined and automatically releases resources upon termination. This is configured with int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate), returning EINVAL for invalid states. Another attribute is stack size, set using pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) to specify the minimum stack allocation in bytes; it must be at least {PTHREAD_STACK_MIN} and not exceed system limits, or EINVAL is returned. The getter pthread_attr_getstacksize() retrieves this value. Scheduling attributes control execution and , essential for applications. The scheduling is set with pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy), supporting SCHED_FIFO for first-in-first-out real-time scheduling where threads run until completion or blockage, SCHED_RR for time-slicing among equal- threads, and SCHED_OTHER for the implementation-defined non- ; ENOTSUP is returned if a is unsupported, and EINVAL for invalid values. Scheduling , set via pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit), defaults to PTHREAD_INHERIT_SCHED, where the new thread inherits and parameters from its creator, ignoring the attributes object; PTHREAD_EXPLICIT_SCHED uses the explicit values from the object instead. Both and are guarded by this mode. Priority is managed through the struct sched_param, set with pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param), which specifies the sched_priority field for policies like SCHED_FIFO and SCHED_RR; higher values indicate higher priority, but scheduling requires appropriate system privileges, such as access on many implementations. Invalid priorities yield EINVAL, and unsupported parameters return ENOTSUP. The getter pthread_attr_getschedparam() retrieves these values. These attributes collectively enable fine-tuned control over thread behavior, particularly in environments demanding predictable timing.

Thread-Specific Data and Keys

Thread-specific data (TSD) in pthreads provides a mechanism for each thread to associate private with a global key, avoiding the need for global variables or thread identifiers in data structures. This allows threads to maintain independent copies of items, such as error states or context information, without interference from other threads in the process. The standard defines TSD through opaque keys of type pthread_key_t, which are created process-wide but hold thread-unique values. To create a TSD key, the pthread_key_create() function is used, which allocates a new key visible to all threads and optionally associates a destructor function of type void (*destructor)(void *) that will be invoked upon thread termination. The function takes a pointer to a pthread_key_t variable to store the key and returns 0 on success; if a destructor is provided, it is called automatically when a thread exits if the value associated with the key is non-NULL. Keys are deleted with pthread_key_delete(), which invalidates the key but does not trigger destructors for any existing thread-specific values, nor does it affect data in other threads. Access to TSD is managed via pthread_setspecific(pthread_key_t key, const void *value), which binds the provided value to the specified for the calling thread only, overwriting any previous value, and pthread_getspecific(pthread_key_t key), which retrieves the current value bound to the key in the calling thread, returning if no value is set or if the key is invalid. Each thread maintains its own value per key, enabling isolated without overhead for reads and writes within the same thread. If the key has been deleted, calls to these functions yield . The destructor mechanism ensures cleanup of thread-specific resources: upon thread termination, for each key with a non-NULL value, the destructor is invoked with that value as its ; if the value remains non-NULL after the call (e.g., if the destructor reallocates or fails to free it), the process repeats up to PTHREAD_DESTRUCTOR_ITERATIONS times, though the exact order of destructor calls across multiple keys is unspecified. This behavior helps handle cases where destructors might set new values, but it is limited to prevent infinite loops. As noted in the termination , these are triggered during normal thread exit. Common use cases for TSD include per-thread storage for the errno variable, which POSIX requires to be thread-local to avoid corruption across concurrent library calls, and maintaining logging contexts such as thread identifiers or user-defined sessions without global state. Implementations typically limit the number of keys per process to PTHREAD_KEYS_MAX, often 128 or more depending on the system. Errors for these operations include EAGAIN for pthread_key_create() when the system-imposed limit on keys (PTHREAD_KEYS_MAX) is reached or resources are temporarily unavailable, and ENOMEM if insufficient exists for the key allocation. For pthread_setspecific() and pthread_getspecific(), EINVAL is returned if the is invalid (e.g., uninitialized or deleted). Other functions like pthread_key_delete() are typically non-erroring but may fail under resource constraints in some implementations.

Cancellation and Cleanup

In threads (pthreads), thread cancellation provides a mechanism for asynchronously terminating a thread in a controlled manner, distinct from normal termination via pthread_exit(). The pthread_cancel() function requests the cancellation of a specified thread by its ID. This function operates asynchronously with respect to the calling thread and returns immediately, but the actual cancellation effect depends on the target thread's cancelability state and type. Upon successful cancellation, the thread's cleanup handlers are invoked, followed by any thread-specific data destructors, and the thread terminates with a status of PTHREAD_CANCELED. The cancelability state determines whether a thread can be canceled at all, controlled by pthread_setcancelstate(), which atomically sets the state to either PTHREAD_CANCEL_ENABLE (default, allowing cancellation) or PTHREAD_CANCEL_DISABLE (preventing cancellation, queuing pending requests until re-enabled). The cancelability type, set via pthread_setcanceltype(), specifies when cancellation occurs: PTHREAD_CANCEL_DEFERRED (default, postponing cancellation until the thread reaches a cancellation point) or PTHREAD_CANCEL_ASYNCHRONOUS (allowing immediate cancellation at any point). Newly created threads, including the initial thread, start with cancellation enabled and deferred. Asynchronous cancellation is generally discouraged for resource-holding threads due to potential cleanup issues, as it may interrupt operations unpredictably. Cancellation points are specific locations where a checks for pending cancellations when using deferred type, including standard functions like pthread_cond_wait(), pthread_join(), read(), and write(). Developers can introduce explicit cancellation points using pthread_testcancel(), which has no effect if cancellation is disabled but otherwise acts as a check for pending requests. To ensure safe interruption in long-running tasks without relying solely on implicit points, pthread_testcancel() should be called periodically, such as in loops processing extended computations. Cleanup handlers manage resource deallocation during cancellation or normal exit, registered using pthread_cleanup_push() and pthread_cleanup_pop(), which must appear as paired statements in the same lexical scope (often implemented as macros). The push function adds a handler routine and argument to the thread's cleanup stack; the pop function removes the top handler and optionally executes it if the execute argument is non-zero. Handlers execute in reverse order (last-in, first-out) when the thread is canceled or calls pthread_exit(), with cancellation disabled during their execution to prevent recursive cancellation. A common use is unlocking mutexes or freeing allocated resources, ensuring thread-safe cleanup even if cancellation interrupts a —for instance:
c
pthread_cleanup_push(cleanup_mutex, &mutex);
pthread_mutex_lock(&mutex);
// [Critical section](/page/Critical_section) code
pthread_mutex_unlock(&mutex);
pthread_cleanup_pop(0);  // No execute on normal pop
If cancellation occurs within the section, the handler unlocks the mutex. The pthread_cancel() function returns 0 on success or an ; common errors include ESRCH if no thread corresponds to the given ID. Both pthread_setcancelstate() and pthread_setcanceltype() return EINVAL for invalid state or type arguments. Cancellation requests to disabled threads are held pending until enabled, but EPERM may arise in implementations if the target thread cannot be canceled due to permissions or state (though specifies it primarily for related functions like pthread_kill()). Best practices recommend deferred cancellation for most scenarios to allow proper , disabling cancellation in critical sections via pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, [NULL](/page/Null)) and re-enabling afterward with a pthread_testcancel() call. Asynchronous cancellation should be avoided in signal handlers or when threads hold shared resources, as only pthread_cancel(), pthread_setcancelstate(), and pthread_setcanceltype() are guaranteed async-cancel safe. This mechanism is particularly suited for gracefully terminating long-running threads, such as those in servers handling indefinite I/O operations.

Implementations

On POSIX-Compliant Systems

On -compliant systems, the Threads (pthreads) is implemented natively through user-space libraries backed by kernel-level support, enabling efficient multithreading on operating systems. The Native Thread Library (NPTL), part of the GNU C Library (), serves as the primary implementation on distributions. Introduced with version 2.6 in 2003, NPTL provides full conformance to the .1 standard by mapping each user-level thread directly to a kernel scheduling entity in a 1:1 model, eliminating the need for user-space thread management and improving scalability for applications with thousands of threads. In the BSD family of operating systems, pthreads are implemented via dedicated libraries such as libthr in , which adopts a 1:1 threading model where each pthread corresponds to a thread ( or LWP) for direct scheduling. Similarly, uses libpthread in a 1:1 implementation, with threads independently scheduled by the since its introduction as the default in OpenBSD 5.2. employs libpthread in a 1:1 model, ensuring each thread maps to a LWP for POSIX.1-2001 compliance. has provided native pthreads support since Solaris 9 through libpthread, utilizing a 1:1 threading model that maps threads to entities for enhanced performance and stability without requiring MxN user-kernel mapping. On macOS, pthreads are supported via the libSystem dynamic library, which integrates libpthread as part of the core system framework, maintaining compatibility while coexisting with higher-level abstractions like Grand Central Dispatch (GCD). Performance in these native implementations benefits from the 1:1 user- threading model, which allows direct kernel scheduling and reduces overhead compared to earlier many-to-one or many-to-many approaches. On with NPTL, synchronization primitives such as mutexes and condition variables leverage futexes (fast user-space mutexes), enabling lock-free operations in uncontended cases via atomic instructions, with kernel intervention only for contention, thus achieving low-latency even in shared-memory scenarios across processes. This model supports high scalability, with benchmarks showing thread creation times reduced by up to 7 times and synchronization overhead minimized through futex wait queues. While adhering to the POSIX core, some implementations include platform-specific extensions. In glibc on Linux, non-POSIX extensions such as pthread_setname_np and pthread_getname_np allow setting and retrieving thread names for debugging purposes, enhancing observability without altering standard behavior. These extensions are optional and marked as non-portable to maintain compatibility across systems. Diagnostics for pthreads applications on POSIX systems commonly involve tools like the GNU Debugger (GDB), which supports multi-threaded debugging by allowing inspection of thread states, stack traces, and breakpoints per thread via commands such as info threads and thread apply all. For detecting race conditions and synchronization errors, Valgrind's Helgrind tool analyzes pthreads usage, reporting data races, lock order violations, and misuse of primitives like mutexes, with minimal runtime overhead for production-like testing.

Portability to Non-POSIX Platforms

Windows lacks native support for threads (pthreads), necessitating the use of compatibility libraries that map pthreads APIs to the underlying Win32 threading model. The primary such library is pthreads4w (also known as pthreads-win32), an open-source implementation that provides a substantial subset of the 1003.1c standard by emulating pthreads functionality atop Win32 primitives, such as using Critical Sections for mutexes and events for condition variables. Another option is the winpthreads library integrated into toolchains, which similarly layers pthreads compatibility over Win32 threads to enable -style programming in Windows environments compiled with . On other non- platforms, pthreads portability often relies on emulation layers. Cygwin, a emulation environment for Windows, includes built-in support for pthreads, allowing Unix applications to run with minimal modifications by translating calls to Win32 equivalents. In contrast, Microsoft's Subsystem for UNIX-based Applications (SUA), which previously offered pthreads via a subsystem, has been deprecated and is no longer available in modern Windows releases. Porting pthreads to non- systems introduces several challenges, including differences in thread scheduling and mechanisms. For instance, employs a contiguous range, while Win32 uses discrete classes (e.g., to ) with relative levels within process-specific subsets, requiring libraries like pthreads4w to perform non-trivial mappings that may not preserve exact semantics. Signal handling poses additional limitations, as Windows lacks direct equivalents to signals, leading to incomplete or emulated support in wrappers that can result in unexpected behavior for signal-dependent code. Furthermore, the translation layer incurs performance overhead, such as increased latency in synchronization operations due to the indirection between abstractions and native APIs. For better integration on Windows, alternatives to pthreads wrappers include using the native Win32 API directly, which offers fine-grained control over threads but requires platform-specific code, or adopting the threads standard (<threads.h>), now supported in 2022 and later for portable concurrency without dependencies. As of 2025, pthreads4w remains actively maintained, with version 3.0.0 released under the Apache License 2.0, supporting both 32-bit and 64-bit Windows, and continues to facilitate cross-platform development in various open-source projects.

Examples

Basic Thread Creation

Basic thread creation in pthreads involves using the pthread_create function to spawn new s of execution within a , allowing concurrent task handling on multi-core systems. This foundational operation enables developers to leverage parallelism for improved in applications like servers or simulations, where tasks can run independently without shared state modifications in this introductory context. The standard defines pthread_create as the primary mechanism for initiating a , specifying the thread's starting routine and arguments, while pthread_join ensures the creating thread waits for the new thread's completion to synchronize execution flow. A simple C program demonstrates this by creating multiple threads that each print their unique thread ID and perform a brief sleep, illustrating concurrent execution without data races since no shared resources are accessed.
c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define NUM_THREADS 5

void* thread_function(void* arg) {
    int thread_id = *(int*)arg;
    printf("Thread %d starting\n", thread_id);
    sleep(1);  // Simulate work
    printf("Thread %d finishing\n", thread_id);
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];
    int thread_args[NUM_THREADS];
    int rc, i;

    for (i = 0; i < NUM_THREADS; i++) {
        thread_args[i] = i;
        rc = pthread_create(&threads[i], NULL, [thread_function](/page/thread_function), &thread_args[i]);
        if (rc != 0) {
            printf("Failed to create thread %d: %d\n", i, rc);
            return 1;
        }
    }

    for (i = 0; i < NUM_THREADS; i++) {
        [pthread_join](/page/pthread_join)(threads[i], NULL);
    }

    printf("All threads completed\n");
    return 0;
}
To compile this program on a POSIX-compliant system, use the command gcc -o example example.c -lpthread, linking against the pthread library as required by the standard for multithreading support. In the example, the main thread iterates to create five threads using pthread_create, passing a thread ID as an integer argument via a pointer to enable distinct identification; error checking verifies the return code to handle creation failures, such as resource limits. Each thread executes the thread_function, which dereferences the argument to access its ID, prints status messages, and sleeps for one second to mimic computational work, demonstrating how threads run concurrently and interleave output based on scheduler decisions. The main thread then calls pthread_join for each thread in a loop, blocking until all complete, ensuring orderly program termination and resource cleanup; sample output might appear as "Thread 2 starting", "Thread 0 starting", "Thread 1 starting", followed by interleaved finishing messages and finally "All threads completed", highlighting non-deterministic execution order due to parallelism. This approach teaches essential practices: passing arguments by pointer to avoid copying complex data, checking return values for robustness (where zero indicates success per POSIX), and joining threads to prevent zombie processes.

Synchronized Multithreading

Synchronized multithreading in pthreads enables safe coordination between threads sharing data structures, as demonstrated by the classic . In this scenario, a producer thread generates items and adds them to a bounded shared queue, while a consumer thread removes and processes them, preventing overflows or underflows through synchronization primitives. This example uses a to protect the queue and two to signal when the queue is not full (for producers) or not empty (for consumers), ensuring threads wait only when necessary and resume upon relevant changes. The following C code implements a simple producer-consumer system with a fixed-size circular buffer. The buffer is protected by a mutex, and condition variables handle waiting for space or items. Initialization occurs in the main function, with proper destruction at the end to release resources.
c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define BUFFER_SIZE 5
#define NUM_ITEMS 10

int buffer[BUFFER_SIZE];
int count = 0;
int head = 0;
int tail = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;
pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER;

void *producer(void *arg) {
    for (int i = 0; i < NUM_ITEMS; i++) {
        pthread_mutex_lock(&mutex);
        while (count == BUFFER_SIZE) {
            pthread_cond_wait(&not_full, &mutex);
        }
        buffer[head] = i;
        head = (head + 1) % BUFFER_SIZE;
        count++;
        printf("Produced item %d\n", i);
        pthread_cond_signal(&not_empty);
        pthread_mutex_unlock(&mutex);
        sleep(1);  // Simulate production time
    }
    return NULL;
}

void *consumer(void *arg) {
    for (int i = 0; i < NUM_ITEMS; i++) {
        pthread_mutex_lock(&mutex);
        while (count == 0) {
            pthread_cond_wait(&not_empty, &mutex);
        }
        int item = buffer[tail];
        tail = (tail + 1) % BUFFER_SIZE;
        count--;
        printf("Consumed item %d\n", item);
        pthread_cond_signal(&not_full);
        pthread_mutex_unlock(&mutex);
        sleep(2);  // Simulate consumption time
    }
    return NULL;
}

int main() {
    pthread_t prod_thread, cons_thread;

    if (pthread_create(&prod_thread, NULL, producer, NULL) != 0) {
        perror("Producer thread creation failed");
        exit(1);
    }
    if (pthread_create(&cons_thread, NULL, consumer, NULL) != 0) {
        perror("Consumer thread creation failed");
        exit(1);
    }

    pthread_join(prod_thread, NULL);
    pthread_join(cons_thread, NULL);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&not_full);
    pthread_cond_destroy(&not_empty);

    return 0;
}
This implementation avoids race conditions by acquiring the mutex before checking or modifying the buffer state, releasing it only after signaling. The while loops with pthread_cond_wait ensure the predicate (buffer not full or not empty) holds upon wakeup, handling spurious signals as required by the POSIX standard. When the buffer is full, the producer waits on not_full (atomically releasing the mutex), and the consumer signals it upon consuming an item; conversely, an empty buffer causes the consumer to wait on not_empty until the producer signals availability. For robustness, error handling should check return values of all pthread functions, as shown in the main function for thread creation; failures like resource exhaustion can be logged or handled gracefully. To extend to multiple producers, the would broadcast on not_full using pthread_cond_broadcast after consuming to wake all waiting producers, preventing while maintaining efficiency for single-consumer cases.

References

  1. [1]
    Threads
    Threads define interfaces and functionality to support multiple flows of control within a process, defining system interfaces for application portability.
  2. [2]
    pthreads(7) - Linux manual page - man7.org
    POSIX.1-2001 and POSIX.1-2008 require that all functions specified in the standard shall be thread-safe, except for the following functions: asctime ...
  3. [3]
    IEEE 1003.1c-1995
    IEEE 1003.1c-1995. Standard for Information Technology--Portable Operating System Interface (POSIX(™)) - System Application Program Interface (API) ...
  4. [4]
    POSIX Threads API
    A POSIX thread is a single flow of control within a process. It shares a virtual address space with other threads in the same process.
  5. [5]
    CS360 Lecture notes -- Thread #1 - UTK-EECS
    What are threads? Threads are often called "lightweight processes". Whereas a typical process in Unix consists of CPU state (i.e. registers), memory (code, ...
  6. [6]
    The Single UNIX Specification, Version 2 Threads Extensions
    The X/Open Threads Extension is built upon the threads model and interfaces defined in IEEE Std 1003.1c-1995, commonly known as POSIX.1c or Pthreads. POSIX ...
  7. [7]
    POSIX Threads Test Suite - The Open Group
    VSTH verifies the IEEE Std POSIX® 1003.1c-1995 Threads (pthreads) extension, the X/Open CAE System Interfaces & Headers, Issue 5 Threads (aspen threads), UNIX ...
  8. [8]
    Test Suites - The Open Group
    The Open Group Test Suite for the POSIX Additional Realtime Extensions is known as VSRTE. It is a standalone test suite covering POSIX 1003.1d - 1999 and any ...
  9. [9]
    C11 defects: C threads are not realizable with POSIX threads
    Oct 14, 2012 · The semantic specification of C11 threads is in parts so loose, that a stringent implementation of C11 threads on top of POSIX doesn't seem possible.
  10. [10]
    [PDF] Threads and the Single UNIX Specification, Version 2
    _POSIX_THREAD_SAFE_FUNCTIONS — is required to be supported whenever the threads option is supported; the others need not be for POSIX threads.
  11. [11]
    UNIX® Certification Program | www.opengroup.org
    UNIX certification is a vendor-neutral benchmark for open systems, ensuring compliance with the Single UNIX Specification, and is a trusted industry standard.Missing: Linux BSD pthreads
  12. [12]
    Transcending POSIX: The End of an Era? - USENIX
    Sep 8, 2022 · In POSIX, threads emerged in the early 1990s from the need to support parallelism of multicore hardware and enable application-level ...
  13. [13]
    A Programmer's Overview of the POSIX.1d Draft Standard - USENIX
    The standards body responsible for the development and maintenance of all the POSIX standards is the IEEE Portable Applications Standards Committee (PASC). The ...<|separator|>
  14. [14]
    [PDF] The Mach System - UTK-EECS
    In fact, C threads is one of the major influences on the POSIX Pthreads standard, which many operating systems are being modified to support. As a result ...
  15. [15]
    Chapter 8 Programming With Solaris Threads
    This chapter compares the Application Programming Interface (API) for Solaris and POSIX threads, and explains the Solaris features that are not found in POSIX ...
  16. [16]
    [PDF] thesignals ta cktrickforuser - space threadcre at ion - USENIX
    On the other hand, LinuxThreads [29] under GNU/Linux uses a 1:1 mapping and pure user-space implementations like GNU Pth, FSU pthreads or MIT pthreads, etc.
  17. [17]
    The Open Group Base Specifications Issue 7
    POSIX.1-2008 defines a standard operating system interface and environment, including a command interpreter (or “shell”), and common utility programs.<|control11|><|separator|>
  18. [18]
    POSIX™ 1003.1 Frequently Asked Questions (FAQ Version 1.18)
    May 25, 2025 · This is the Frequently Asked Questions file for the POSIX 1003.1 standard (IEEE Std 1003.1). Its maintainer is Andrew Josey (ajosey at The Open Group).
  19. [19]
    Rationale: Detailed ToC
    The Open Group Base Specifications Issue 7. IEEE Std 1003.1-2008. Copyright © 2008 The IEEE and The Open Group. Rationale: Detailed ToC.
  20. [20]
    The Austin Common Standards Revision Group - The Open Group
    We're currently working on a major revision with expected output in 2023. We meet regularly at least bi-weekly by teleconference.Missing: pthreads | Show results with:pthreads
  21. [21]
    ISO/IEC/IEEE 9945:2009 - Information technology
    2–5 day deliveryISO/IEC/IEEE 9945:2009 defines a standard operating system interface and environment, including a command interpreter (or "shell"), and common utility programs.
  22. [22]
  23. [23]
    Multi-Threaded Programming With POSIX Threads
    This tutorial explains the different tools defined by the pthread library, shows how to use them, and gives examples of using them to solve real life ...
  24. [24]
  25. [25]
    pthread_create
    ### Summary of Thread Creation in POSIX (pthread_create)
  26. [26]
  27. [27]
  28. [28]
    POSIX Threads Programming
    POSIX threads (Pthreads) are a standardized C interface for UNIX systems, defined by the IEEE POSIX 1003.1c standard, using C language types and procedure ...
  29. [29]
    pthread_exit
    ### Summary of pthread_exit from https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_exit.html
  30. [30]
    pthread_attr_getstacksize
    ### Summary of Thread Stack Allocation
  31. [31]
    pthread_sigmask
    ### Summary of Signal Handling Per Thread
  32. [32]
    pthread_join
    ### Summary of pthread_join from https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html
  33. [33]
    pthread_detach
    ### Summary: Detached vs Joinable Threads and Resource Reclamation
  34. [34]
    pthread_create
    The pthread_create() function shall create a new thread, with attributes specified by attr, within a process. If attr is NULL, the default attributes shall ...
  35. [35]
    pthread_create(3) - Linux manual page - man7.org
    The pthread_create() function starts a new thread in the calling process. The new thread starts execution by invoking start_routine(); arg is passed as the sole ...
  36. [36]
  37. [37]
    pthread_mutex_destroy
    ### Summary of pthread_mutex_init and Related Details
  38. [38]
    pthread_mutex_lock
    The mutex object referenced by mutex shall be locked by calling pthread_mutex_lock(). If the mutex is already locked, the calling thread shall block until the ...
  39. [39]
    pthread_mutex_lock
    ### Summary of pthread_mutex_unlock
  40. [40]
    pthread_mutex_lock
    ### Summary of pthread_mutex_trylock
  41. [41]
    pthread_mutexattr_gettype
    ### Summary of Mutex Types from pthread_mutexattr_settype Documentation
  42. [42]
    pthread_mutexattr_getrobust
    ### POSIX Standard Definition of Robust Mutexes
  43. [43]
  44. [44]
    pthread_mutex_timedlock
    ### Summary of pthread_mutex_timedlock for Timeouts
  45. [45]
    pthread_cond_wait
    The pthread_cond_wait() and pthread_cond_timedwait() functions are used to block on a condition variable. They are called with mutex locked by the calling ...
  46. [46]
    pthread_cond_init
    ### Summary of `pthread_cond_init` from https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_init.html
  47. [47]
    pthread_cond_wait
    ### Summary of pthread_cond_timedwait Content
  48. [48]
    pthread_cond_signal
    ### Summary of pthread_cond_signal from https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_signal.html
  49. [49]
    pthread_cond_signal
    ### Summary of pthread_cond_broadcast from https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_broadcast.html
  50. [50]
    pthread_cond_init
    ### Summary of pthread_cond_destroy from https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_destroy.html
  51. [51]
  52. [52]
  53. [53]
    None
    Nothing is retrieved...<|control11|><|separator|>
  54. [54]
    pthread_attr_getschedpolicy
    ### Summary of Scheduling Policies for `pthread_attr_setschedpolicy`
  55. [55]
    pthread_attr_getinheritsched
    ### Summary of Scheduling Inheritance: PTHREAD_EXPLICIT_SCHED and PTHREAD_INHERIT_SCHED
  56. [56]
    pthread_attr_getschedparam
    ### Summary: Setting Scheduling Parameters, Priority, and Privileges for Real-Time
  57. [57]
    pthread_key_create
    `pthread_key_create` creates a thread-specific data key visible to all threads, used to locate thread-specific data. It returns zero on success.Missing: documentation | Show results with:documentation
  58. [58]
    pthread_setspecific
    The pthread_setspecific() function associates a thread-specific value with a key obtained via a previous call to pthread_key_create().
  59. [59]
    The Pthreads Library - Multithreaded Programming Guide
    The Pthreads API library has over 100 functions for basic multithreaded programming, including creating threads, waiting for termination, and thread-specific ...
  60. [60]
    pthread_cancel
    The pthread_cancel() function shall request that thread be canceled. The target thread's cancelability state and type determines when the cancellation takes ...
  61. [61]
    pthread_cancel
    The pthread_cancel() function requests that thread be canceled. The target threads cancelability state and type determines when the cancellation takes effect.Missing: documentation | Show results with:documentation
  62. [62]
    pthread_setcancelstate
    The pthread_setcanceltype() function atomically both sets the calling thread's cancelability type to the indicated type and returns the previous cancelability ...Missing: documentation | Show results with:documentation
  63. [63]
    pthread_setcancelstate
    ### Summary of pthread_testcancel
  64. [64]
    pthread_cleanup_push
    The pthread_cleanup_push() function pushes the specified cancellation cleanup handler routine onto the calling thread's cancellation cleanup stack.Missing: documentation | Show results with:documentation<|separator|>
  65. [65]
    Introducing the 2.6 Kernel - Linux Journal
    May 1, 2003 · The result is greatly improved kernel support for threads and a new user-space pthread library, called Native POSIX Threading Library (NPTL), ...
  66. [66]
  67. [67]
    5.2 Threading Model - Oracle® Linux 6
    The GNU C library (glibc) implements Pthreads as the Native POSIX Threads Library (NPTL), where each thread maps to a kernel scheduling entity.<|separator|>
  68. [68]
    pthread - FreeBSD Manual Pages
    IMPLEMENTATION NOTES The current FreeBSD POSIX thread implementation is built into the 1:1 Threading Library (libthr, -lthr) library. It contains thread ...
  69. [69]
    pthreads(3) - OpenBSD manual pages
    In OpenBSD, threads use a 1-to-1 implementation, where every thread is independently scheduled by the kernel. For the purpose of this document, the functions ...
  70. [70]
    pthread(3) - NetBSD Manual Pages
    The pthread library provides an implementation of the standard POSIX threads library. The NetBSD implementation is based on 1:1 thread model, therefore each ...
  71. [71]
    Compiling and Linking a Multithreaded Program
    In the Solaris 9 release, the Solaris threads API and Pthreads API are contained in separate libraries, libthread and libpthread. An application compiled with ...Missing: native | Show results with:native
  72. [72]
    Threading Models in Oracle Solaris and RHEL - Developer's Guide ...
    Threading Models in Oracle Solaris and RHEL · LinuxThreads – The original Pthreads implementation. Since glibc 2.4, this implementation is no longer supported.Missing: 9 | Show results with:9
  73. [73]
    Mac OS X Manual Page For pthread(3) - Apple Developer
    POSIX threads are a set of functions that support applications with requirements for multiple flows of control, called threads, within a process.Missing: libpthread | Show results with:libpthread
  74. [74]
    GCD Internals - NewOSXBook.com
    The underlying support for libdispatch is still the venerable POSIX threads library (pthread), though most of the support comes from non-POSIX compliant ...
  75. [75]
    Measuring context switching and memory overheads for Linux threads
    Sep 4, 2018 · With NPTL, thread creation time became about 7x faster, and synchronization became much faster as well due to the use of futexes. Threads ...<|separator|>
  76. [76]
    7. Helgrind: a thread error detector - Valgrind
    Helgrind is a Valgrind tool for detecting synchronisation errors in C, C++ and Fortran programs that use the POSIX pthreads threading primitives.
  77. [77]
    POSIX Threads for Windows download | SourceForge.net
    Rating 5.0 (2) · Free · WindowsPlease note:- whilst PThreads4W can be built and run by it, MinGW64 includes it's own default POSIX Threads library called "winpthreads". The two are not ...
  78. [78]
    fwbuilder/pthreads4w: POSIX threads API for Windows from ... - GitHub
    Pthreads4w is an Open Source Software implementation of the Threads component of the POSIX 1003.1c 1995 Standard (or later) for Microsoft's Windows environment.
  79. [79]
    mingw-w64
    Runtime Libraries: Winpthreads, a pthreads library for C++11 threading support and simple integration with existing project. Winstorecompat, a work-in-progress ...Pre-built Toolchains · MSYS2 (GCC) · Source Code · Arch Linux
  80. [80]
    Utilities and SDK for Subsystem for UNIX-based Applications in ...
    Jul 15, 2024 · Note that Subsystem for UNIX-based Applications has been deprecated, and will not be available in future releases of Windows or Windows Server.
  81. [81]
    PORTABILITY ISSUES manual page - Thread priority - Sourceware
    An application using Pthreads-w32 should not make assumptions about the numbers used to represent thread priority levels, except that they are monotonic between ...Missing: challenges | Show results with:challenges
  82. [82]
    Pthreads on Microsoft Windows - Lockless Inc
    An extremely common API used for developing parallel programs is the Posix Threads API (pthreads). The API contains many synchronization primitives.<|control11|><|separator|>
  83. [83]
    C11 Threads in Visual Studio 2022 version 17.8 Preview 2
    Sep 26, 2023 · We are happy to announce that support for the other major concurrency feature of C11, threads, is available in Visual Studio version 17.8 ...
  84. [84]
    The Producer/Consumer Problem (Multithreaded Programming Guide)
    The example also has a mutex, as the data structure describing the buffer must be accessed by only one thread at a time. Example 4-11 The Producer/Consumer ...<|control11|><|separator|>
  85. [85]
    Example: Using condition variables in Pthread programs - IBM
    This example shows a Pthread program using condition variables to notify threads of a condition. Notice what mutual exclusion (mutex) locking protocol is used.
  86. [86]
    Using Condition Variables (Multithreaded Programming Guide)
    A condition variable represents a queue of threads waiting for some condition to be signaled. Example 4-11 has two such queues, one ( less ) for producers ...