Document revision date: 30 March 2001

## Guide to the POSIX Threads Library

Previous | Contents | Index

## 1.5 Programming Issues for Multithreaded Programs

Building your multithreaded program must produce executable code that is reentrant. Therefore, be sure that your compiler generates reentrant code before you design or code your multithreaded program. By default, Compaq's C, C++, Ada, Pascal, COBOL, FORTRAN and BLISS compilers generate reentrant code.

If you cannot build your program so that its executable code is reentrant, it might be impossible to keep the program's threads from interfering with each other. See Section 3.9.1 for more information about thread-reentrant libraries.

In general, when using threads, be aware of language-based programming practices that are inherently not thread-safe. ("Thread safety" is explained in Section 3.9.2.) You must address these factors when writing multithreaded applications and thread-safe libraries. For example, FORTRAN language routines typically rely heavily upon static storage, which can prevent those routines from being thread safe.

When you design and code a multithreaded program, you must also accommodate or eliminate, as appropriate, each of the following issues:

- Program complexity is the most significant issue to consider in any multithreaded programming effort. Although using threads can simplify the coding and designing of a program, a certain level of expertise is required to be sure that the design of the synchronization and interplay among threads is appropriate and correctly specified. This level of expertise is higher than that required to design most single-threaded programs.
- Dependence upon other nonreentrant software means that your multithreaded program calls a routine or library that is not equipped to deal with threads. Given this dependence, your program must prevent conflicts with other threads that use the same nonreentrant routine or library. Section 3.9 presents multithreaded programming techniques for managing dependencies upon other nonreentrant software.
- Due to programming errors, race conditions in the program's behavior can cause unpredictable and erroneous program behavior, which depends on, and varies with, the precise timing of the threads' execution. Similarly, deadlocks can cause two or more threads to be blocked from executing indefinitely. Section 3.6.2 discusses race conditions in more detail, and Section 3.6.3 discusses deadlocks.
- Priority inversion prevents high-priority threads from executing when interdependencies exist among three or more threads of different priorities. Section 3.5.2 discusses techniques for avoiding priority inversion.

## 1.6 POSIX Threads Libraries and Interfaces

As a package, the POSIX Threads Library is a collection of shared code libraries and C language header files that declare entry points into those libraries. This guide's platform-specific appendixes describe these libraries in more detail and list all other libraries upon which the Threads Libraries depend.

From the programmer's view, the Threads Libraries offer interfaces. Each interface is a distinct set of routines that together provide a well-defined set of related data objects and operations.

This version of the Threads Library supports two interfaces that are documented in this guide:

- The pthread interface provides multithreading capability in your applications. This interface is based on the Single UNIX Specification (SUSV2), which incorporates the POSIX thread standard (1003.1c-1995). Use this interface to build portable, multithreaded applications.
  Section 1.6.1 introduces the pthread interface. Chapter 2 and Chapter 3 describe how to use the features and functionality of the pthread interface. The reference descriptions in Part 2 describe in detail each routine in the pthread interface.
- The Compaq proprietary tis interface offers routines that provide thread-independent services. The routines in this interface enable your software to perform thread-safe processing that requires synchronization, but without requiring the use of the pthread interface.
  Section 1.6.2 introduces the tis interface. Chapter 4 describes how to use the features and functionality of the tis interface. The reference descriptions in Part 3 describe in detail each routine in the tis interface.

This release of the Threads Library includes interface definitions for the C programming language only. However, all Threads Library routines are callable from languages other than C. Your application must provide its own declarations for Threads Library routines in a manner appropriate for its programming language. These definitions should be modeled after the declarations in the C language `pthread.h` header file.

For backward compatibility, this version of the Threads Library also supports other interfaces that are not documented in this guide. See Section 1.6.3.

Special note when using the Threads Library from non-C languages:

Several Threads Library features and most Threads Library identifiers are provided as C language macros. As such, their definitions may not be available in other languages. Developers working in other languages will have to provide their own declarations of functions and constants. Features such as `TRY/CATCH` exception handling and POSIX push/pop cleanup handlers may be completely unavailable, although it may be possible to provide similar functionality using native exception handling facilities. Note that in this context, C++ is a non-C language; while the C language macros may compile successfully under C++, `TRY/CATCH` and push/pop cleanup handlers are not supported for C++ code. C++ code should use object destructors and C++ exception handlers.

### 1.6.1 The pthread Multithreading Interface

The pthread interface routines implement the IEEE Standard 1003.1-1996, Portable Operating System Interface (or POSIX) Application Program Interface, also known as POSIX.1. It also supports extensions specified in SUSV2 (UNIX98).

Table 1-1 lists and summarizes functionally the pthread interface routines.

The pthread interface contains routines grouped in the following functional categories:

- General threads routines
- Thread attributes object routines
- Thread cancelation routines
- Thread priority, concurrency, and scheduling routines
- Thread-specific data routines
- Mutex routines
- Mutex attributes object routines
- Condition variable routines
- Condition variable attributes object routines
- Read-write lock routines
- Read-write lock attributes object routines

The pthread interface also provides routines that implement nonportable extensions to the POSIX.1 standard. These routines are grouped in these functional categories:

- Thread execution routines
- Global mutex routines
- Mutex attributes routines
- Condition variable routines
- Object naming routines
- Exception object routines

Among the routines in the pthread interface that implement nonportable extensions to the POSIX.1 standard, are the routines in the Threads Library exception package. This package consists of a library and C language header file ( `pthread_exceptions.h` ) that implement a Compaq-specific exception-handling facility. It is designed specifically for use with the pthread interface. Chapter 5 describes the Threads Library exception package.

This guide also documents several routines that are not declared entries in the pthread interface, but that have close affinity with its functionality. Examples are the `sched_yield()` and `sigwait()` routines. See the end of Table 1-1 for a list of these routines.

Table 1-1 pthread Routines Summary
Routine | Description
--- | ---
General Threads Routines
`pthread_atfork()` | Declares fork handler routines to be called
`pthread_create()` | Creates a thread object and thread
`pthread_detach()` | Marks a thread object for deletion
`pthread_equal()` | Compares one thread identifier to another thread identifier
`pthread_exit()` | Terminates the calling thread
`pthread_join()` | Causes the calling thread to wait for the termination of a specified thread and detach it
`pthread_kill()` | Delivers a signal to a specified thread
`pthread_once()` | Calls an initialization routine to be executed only once
`pthread_self()` | Obtains the identifier of the calling thread
`pthread_sigmask()` | Examines or changes the calling thread's signal mask
Thread Attributes Object Routines
`pthread_attr_destroy()` | Destroys a thread attributes object
`pthread_attr_getdetachstate()` | Obtains the detachstate attribute of the specified thread attributes object
`pthread_attr_getguardsize()` | Obtains the guardsize attribute of the specified thread attributes object
`pthread_attr_getinheritsched()` | Obtains the inherit scheduling attribute of the specified thread attributes object
`pthread_attr_getschedparam()` | Obtains the scheduling parameters for the scheduling policy attribute of the specified thread attributes object
`pthread_attr_getschedpolicy()` | Obtains the scheduling policy attribute of the specified thread attributes object
`pthread_attr_getscope()` | Obtains the contention-scope attribute of the specified thread attributes object
`pthread_attr_getstackaddr()` | Obtains the stackaddr attribute of the specified thread attributes object
`pthread_attr_getstacksize()` | Obtains the stacksize attribute of the specified thread attributes object
`pthread_attr_init()` | Initializes a thread attributes object
`pthread_attr_setdetachstate()` | Changes the detachstate attribute of the specified thread attributes object
`pthread_attr_setguardsize()` | Changes the guardsize attribute of the specified thread attributes object
`pthread_attr_setinheritsched()` | Changes the inherit scheduling attribute of the specified thread attributes object
`pthread_attr_setschedparam()` | Changes the values of the parameters associated with the scheduling policy attribute of the specified thread attributes object
`pthread_attr_setschedpolicy()` | Changes the scheduling policy attribute of the specified thread attributes object
`pthread_attr_setscope()` | Changes the contention-scope attribute of the specified thread attributes object
`pthread_attr_setstackaddr()` | Changes the stackaddr attribute of the specified thread attributes object
`pthread_attr_setstacksize()` | Changes the stacksize attribute of the specified thread attributes object
Thread Cancelation Routines
`pthread_cancel()` | Allows a thread to request that it, or another thread, terminate execution
`pthread_cleanup_pop()` | Removes a cleanup handler routine from the top of the "cleanup stack" and optionally executes it
`pthread_cleanup_push()` | Establishes a cleanup handler routine to be executed when the thread exits or is canceled while the handler is on the "cleanup stack"
`pthread_setcancelstate()` | Sets the calling thread's cancelability state to enable or disable the delivery of cancelation requests
`pthread_setcanceltype()` | Sets the calling thread's cancelability type to enable or disable the delivery of cancelation requests
`pthread_testcancel()` | Requests delivery of any pending cancelation request to the calling thread
Thread Priority, Concurrency, and Scheduling Routines
`pthread_getconcurrency()` | Obtains the current concurrency level parameter for the process
`pthread_getschedparam()` | Obtains the current scheduling policy and scheduling parameters of a thread
`pthread_setconcurrency()` | Changes the current concurrency level parameter for the process
`pthread_setschedparam()` | Changes the current scheduling policy and scheduling parameters of a thread
Thread-Specific Data Routines
`pthread_getspecific()` | Obtains the thread-specific data value associated with the specified key
`pthread_key_create()` | Generates a unique thread-specific data key for the calling thread
`pthread_key_delete()` | Deletes a thread-specific data key
`pthread_setspecific()` | Changes the thread-specific data value associated with the specified key for the calling thread
Mutex Routines
`pthread_mutex_destroy()` | Destroys a mutex
`pthread_mutex_init()` | Initializes a mutex with attributes specified by the attributes argument
`pthread_mutex_lock()` | Locks an unlocked mutex; if locked, the caller waits for the mutex to become available before locking it
`pthread_mutex_trylock()` | Attempts to lock a mutex; returns immediately if mutex is already locked
`pthread_mutex_unlock()` | Unlocks a mutex locked by the calling thread
Mutex Attributes Object Routines
`pthread_mutexattr_destroy()` | Destroys a mutex attributes object
`pthread_mutexattr_getpshared()` | Obtains the process-shared attribute from the specified mutex attributes object
`pthread_mutexattr_gettype()` | Obtains the mutex type attribute from the specified mutex attributes object
`pthread_mutexattr_init()` | Initializes a mutex attributes object
`pthread_mutexattr_setpshared()` | Changes the process-shared attribute in the specified mutex attributes object
`pthread_mutexattr_settype()` | Changes the mutex type attribute in the specified mutex attributes object
Condition Variable Routines
`pthread_cond_broadcast()` | Wakes all threads currently waiting on a condition variable
`pthread_cond_destroy()` | Destroys a condition variable
`pthread_cond_init()` | Initializes a condition variable
`pthread_cond_signal()` | Wakes at least one thread that is waiting on a condition variable
`pthread_cond_timedwait()` | Causes a thread to wait a specified period of time for a condition variable to be signaled or broadcast
`pthread_cond_wait()` | Causes a thread to wait for a condition variable to be signaled or broadcast
Condition Variable Attributes Object Routines
`pthread_condattr_destroy()` | Destroys a condition variable attributes object
`pthread_condattr_getpshared()` | Obtains the process-shared attribute from the specified condition variable attributes object
`pthread_condattr_init()` | Initializes a condition variable attributes object
`pthread_condattr_setpshared()` | Changes the process-shared attribute in the specified condition variable attributes object
Read-Write Lock Routines
`pthread_rwlock_destroy()` | Destroys a read-write lock object
`pthread_rwlock_init()` | Initializes a read-write lock object
`pthread_rwlock_rdlock()` | Acquires a read-write lock for read access; if locked, the caller waits for the lock to become available before locking it
`pthread_rwlock_tryrdlock()` | Acquires a read-write lock for read access without waiting
`pthread_rwlock_trywrlock()` | Acquires a a read-write lock for write access without waiting
`pthread_rwlock_unlock()` | Releases a read-write lock previously acquired by the calling thread
`pthread_rwlock_wrlock()` | Acquires a read-write lock for write access; if locked, the caller waits for the lock to become available before locking it
Read-Write Lock Attributes Object Routines
`pthread_rwlockattr_destroy()` | Destroys a read-write lock attributes object
`pthread_rwlockattr_getpshared()` | Obtains the process-shared attribute from the specified read-write lock attributes object
`pthread_rwlockattr_init()` | Initializes a read-write lock attributes object
`pthread_rwlockattr_setpshared()` | Changes the process-shared attribute in the specified read-write lock attributes object
Nonportable Extensions
`pthread_delay_np()` | Pauses the calling thread's execution for the specified time interval
`pthread_get_expiration_np()` | Calculates a timeout for a timed condition variable wait
`pthread_getsequence_np()` | Gets a small integer specific to the calling thread
`pthread_attr_getstackaddr_np()` | Obtains the address and size of the specified thread attributes object
`pthread_attr_setstackaddr_np()` | Sets the address and size of the specified thread attributes object
`pthread_lock_global_np()` | Locks the global mutex
`pthread_unlock_global_np()` | Unlocks the global mutex
`pthread_cond_signal_int_np()` | Requests condition variable signal from software interrupt routine
`pthread_cond_sig_preempt_int_np()` | Wakes one thread that is waiting on the specified condition variable; called from software interrupt routine
`pthread_attr_getname_np()` `pthread_attr_setname_np()` `pthread_cond_getname_np()` `pthread_cond_setname_np()` `pthread_getname_np()` `pthread_key_getname_np()` `pthread_key_setname_np()` `pthread_mutex_getname_np()` `pthread_mutex_setname_np()` `pthread_rwlock_getname_np()` `pthread_rwlock_setname_np()` `pthread_setname_np()` | Gets/sets name associated with specific objects for debugging
`pthread_exc_get_status_np()` `pthread_exc_matches_np()` `pthread_exc_report_np()` `pthread_exc_set_status_np()` | Exception object routines (some are macros)
`pthread_yield_np()` | Notifies the scheduler that the current thread is willing to release its processor to other threads of the same or higher priority (alias for `sched_yield()` )
Related Standard Routines
`sched_get_priority_max()` | Returns the maximum priority for the specified scheduling policy
`sched_get_priority_min()` | Returns the minimum priority for the specified scheduling policy
`sched_yield()` | Notifies the scheduler that the calling thread is willing to release its processor to other threads of the same or higher priority
`sigwait()` | Suspends a calling thread until a signal arrives

Previous | Next | Contents | Index

| privacy and legal statement |
6101PRO_001.HTML