Document revision date: 30 March 2001

## Guide to the POSIX Threads Library

Previous | Contents | Index

#### 1.6.1.1 Optionally Implemented POSIX.1 Routines

In this version of the Threads Library, the pthread interface does not support the following features that are specified in the POSIX.1 standard:

- Reported by the POSIX.1 `_POSIX_THREAD_PRIO_PROTECT` macro:

  > `pthread_mutex_getprioceiling()`
  > `pthread_mutex_setprioceiling()`
  > `pthread_mutexattr_getprioceiling()`
  > `pthread_mutexattr_setprioceiling()`

- Reported by the POSIX.1 `_POSIX_THREAD_PRIO_PROTECT` and
  `_POSIX_THREAD_PRIO_INHERIT` macros:

  > `pthread_mutexattr_getprotocol()`
  > `pthread_mutexattr_setprotocol()`

- (Not supported for OpenVMS systems) Reported by the POSIX.1 `_POSIX_THREAD_PROCESS_SHARED` macro:

  > `pthread_condattr_getpshared()`
  > `pthread_condattr_setpshared()`
  > `pthread_mutexattr_getpshared()`
  > `pthread_mutexattr_setpshared()`
  > `pthread_rwlockattr_getpshared()`
  > `pthread_rwlockattr_setpshared()`

The POSIX.1 standard directs the Threads Library to provide the macros named `_POSIX_THREAD_PROCESS_SHARED` , `_POSIX_THREAD_PRIO_PROTECT` , and `_POSIX_THREAD_PRIO_INHERIT` to report whether optionally implemented routines are present.

The Threads Library does provide the following macros specified in the POSIX.1 standard:

> `_POSIX_THREADS` : threads are supported
> `_POSIX_THREAD_SAFE_FUNCTIONS` : thread-safe libraries are supported
> `_POSIX_THREAD_ATTR_STACKSIZE` : can specify stack size
> `_POSIX_THREAD_ATTR_STACKADDR` : can specify stack address
> `_POSIX_THREAD_PRIORITY_SCHEDULING` : real-time scheduling control is supported
> `_POSIX_THREAD_PROCESS_SHARED` : cross-process synchronization is supported (Tru64 UNIX only)

### 1.6.2 Thread-Independent Services Interface

The Compaq proprietary tis interface offers a set of thread-independent services. Use these routines to build software that performs processing that requires synchronization, but without requiring the use of pthreads. That is, use tis routines to build thread-safe code libraries whose routines can be called from either a single-threaded or a multithreaded environment.

In the absence of threads, tis routines impose minimal overhead on the calling program. For instance, tis routines avoid the use of interlocked instructions and memory barriers.

When threads are present, tis routines provide full support for synchronization. Note that there are no tis routines for creating threads or thread objects, because these routines would have no meaning if called from a single-threaded environment.

The tis routines can be classified into these functional categories:

- General routines
- Thread cancelation routines
- Thread-specific data key routines
- Mutex routines
- Condition variable routines
- Read-write lock routines

Note Unlike the other tis interfaces, the read-write lock functions work on a data type different from that used by the pthread read-write lock functions.

Table 1-2 summarizes these groups of tis routines.

Table 1-2 tis Routines Summary
Routine | Description
--- | ---
General Routines
`tis_once()` | Calls an initialization routine to be executed only once
`tis_self()` | Obtains the identifier of the calling thread
`tis_yield()` | Notifies the scheduler that the calling thread is willing to release its processor to other threads of the same or higher priority
Thread Cancelation Routines
`tis_setcancelstate()` | Sets the calling thread's cancelability state to enable or disable the delivery of cancelation requests
`tis_testcancel()` | Requests delivery of any pending cancelation request to the calling thread
Thread-Specific Data Key Routines
`tis_getspecific()` | Obtains the thread-specific data associated with the specified key for the calling thread
`tis_key_create()` | Generates a unique thread-specific data key
`tis_key_delete()` | Deletes a thread-specific data key
`tis_setspecific()` | Changes the thread-specific data value associated with the specified key for the calling thread
Mutex Routines
`tis_lock_global()` | Locks the global mutex
`tis_mutex_destroy()` | Destroys the specified mutex object
`tis_mutex_init()` | Initializes a mutex object
`tis_mutex_lock()` | Locks the specified mutex, if unlocked
`tis_mutex_trylock()` | Tries to lock the specified mutex
`tis_mutex_unlock()` | Unlocks the specified mutex when locked by the calling thread
`tis_unlock_global()` | Unlocks the global mutex
Condition Variable Routines
`tis_cond_broadcast()` | Wakes all threads currently waiting on the specified condition variable
`tis_cond_destroy()` | Destroys the specified condition variable object
`tis_cond_init()` | Initializes a condition variable object
`tis_cond_signal()` | Wakes at least one thread that is waiting on the specified condition variable
`tis_cond_timedwait()` | Causes a thread to wait a specified period of time for a condition variable to be signaled or broadcast
`tis_cond_wait()` | Causes the calling thread to wait for the specified condition variable to be signaled or broadcast
`tis_get_expiration()` | Calculates a timeout for a timed condition variable wait
OpenVMS I/O Completion Routines
`tis_io_complete()` | Completion AST service routine
`tis_sync()` | Thread-synchronous replacement for `$SYNC` system service
Read-Write Lock Routines
`tis_read_lock()` | Acquires the specified read-write lock for read access
`tis_read_trylock()` | Acquires the specified read-write lock for read access; returns immediately if already locked
`tis_read_unlock()` | Unlocks the specified read-write lock already acquired for read access by the calling thread
`tis_rwlock_destroy()` | Destroys the specified read-write lock object
`tis_rwlock_init()` | Initializes the specified read-write lock object
`tis_write_lock()` | Acquires the specified read-write lock for write access
`tis_write_trylock()` | Acquires the specified read-write lock for write access; returns immediately if already locked
`tis_write_unlock()` | Unlocks the specified read-write lock already acquired for write access by the calling thread

### 1.6.3 Undocumented and Obsolete Interfaces

Previous versions of the Threads Library offered interfaces that under this version are no longer documented.

#### 1.6.3.1 The cma Interface

This version of the Threads Library supports the Compaq proprietary CMA (or cma) interface. The cma interface reports errors by raising exceptions. This interface is layered on top of the pthread interface. This interface is usually available only on Compaq platforms.

Compaq will continue to support existing applications that were developed using the cma interface. Binary compatibility will be supported indefinitely. Nonetheless, Compaq recommends that, as soon as possible, you migrate any cma code in your existing applications to the latest pthread interface, to take advantage of its standard features, portability, and future enhancements.

Routines of the cma interface are not documented in this guide. In this guide see Appendix D for information to help you migrate your cma-based programs and applications to the latest pthread interface.

#### 1.6.3.2 The d4 (DCEthread) Interfaces

Note These obsolete interfaces will be removed in a future Compaq POSIX Threads release. As of that release, both source and binary code using the d4 (DCEthread) interfaces will no longer compile or execute.

For backward compatibility only, this version of the Threads Library retains full binary support for the d4 interfaces. These interfaces are implementations of the IEEE POSIX 1003.4a/Draft 4 document, and are also known as "DCE threads".

These interfaces include both a "standard" interface that reports errors by setting errno and returning a value of -1, and an "exception-returning" interface that, like the cma interface, reports errors by raising exceptions.

The d4 interfaces will not be provided in a future release of the Threads Library. Compaq recommends that you migrate any d4 code in your existing applications to the latest pthread interface, to take advantage of its standard features, portability, and future enhancements.

Routines of the d4 interfaces are not documented in this guide. In this guide see Appendix E for information to help you migrate your d4-based programs and applications to the latest pthread interface.

## Chapter 2
Objects and Operations

This chapter describes operations that act upon the objects supported in the pthread interface.

## 2.1 Threads and Synchronization Objects

A multithreaded program typically manipulates these objects:

- A thread object describes a thread, which refers to a distinct flow of control within a process. After a thread object is created, the Threads Library uses it to maintain information about the thread's state and its associated attributes.
- A mutex serves as a lock for data that is shared among the program's threads. To access data that is guarded by a mutex, a thread must acquire the mutex, access the data, and then release the mutex. Each instance of acquiring a mutex is called a lock acquisition. While a mutex is locked, if other threads attempt to acquire that mutex, those threads must wait for the mutex to be released.
- For data that is shared among a program's threads but is more frequently read than written, use a read-write lock to guard access to the data. Unlike a mutex, more than one thread can acquire the same read-write lock for read access at the same time.
- When associated with a shared data object and its mutex, a condition variable provides a mechanism that allows a thread to wait until a piece of shared data protected by a mutex is placed into a particular state.

## 2.2 Attributes Objects

When your program creates a thread, mutex, read-write lock or condition variable, it can accept the default attributes for that object or specify an existing attributes object (previously created by your program) that contains particular attribute values. You can also change some of the attributes of a thread after it has begun execution---for example, you can change the thread's priority. However, other attributes, such as stack size, are fixed at execution.

To initialize an attributes object, you can use one of the following routines, depending on the type of object to which the attributes apply:

- `pthread_attr_init()` for thread attributes
- `pthread_mutexattr_init()` for mutex attributes
- `pthread_rwlockattr_init()` for read-write lock attributes
- `pthread_condattr_init()` for condition variable attributes

These routines initialize an attributes object with default values for the individual attributes. To modify any attribute values in an attributes object, use one of the " `attr_set` " routines, such as `pthread_attr_setinheritsched()` , described in later sections.

Initializing an attributes object (or changing the values in an attributes object) does not affect the attributes of existing threads, mutexes, read-write locks and condition variables.

To destroy an attributes object, use one of the following routines:

- `pthread_attr_destroy()` for thread attributes objects
- `pthread_condattr_destroy()` for condition variable attributes objects
- `pthread_mutexattr_destroy()` for mutex attributes objects
- `pthread_rwlockattr_destroy()` for read-write lock attributes objects

Deleting an attributes object does not affect the attributes of objects previously created with that attributes object.

## 2.3 Thread Operations

The following sections describe these operations on threads:

- Creating a thread
- Setting the attributes for a new thread
- Terminating a thread
- Detaching and destroying a thread
- Joining with another thread
- Controlling how a thread is scheduled
- Canceling a thread

### 2.3.1 Creating a Thread

Your program creates a thread using the `pthread_create()` routine. This routine creates a thread based on the settings of the thread attributes object if specified, which your program must have previously initialized. If called without a specified thread attributes object, `pthread_create` creates a new thread that has the default attributes.

The Threads Library creates a thread in the ready state and prepares the thread to begin executing its start routine, the function passed to the `pthread_create()` routine. Depending on the presence of other threads and their scheduling attributes, the new thread might preempt its creator (that is, it might start before the call to `pthread_create()` returns). The caller of `pthread_create()` can synchronize with the new thread using any mutually agreed upon mechanism or await its termination using `pthread_join()` .

The Threads Library assigns each new thread a thread identifier, which is written into the address specified as the `pthread_create()` routine's thread argument. The new thread's identifier is written before the new thread executes.

You can create a thread that is detached. To do so, create a thread using a thread attributes object whose detachstate attribute has been set, using the `pthread_attr_setdetachstate()` routine, to `PTHREAD_CREATE_DETACHED` . This is useful for creating a thread that your program knows will not be joined by any other thread. That is, when such a thread terminates, the thread and its thread object are automatically destroyed.

For more detailed information about thread creation, see the reference description of the `pthread_create()` routine in Part 2.

### 2.3.2 Setting the Attributes of a New Thread

When creating a thread, your program can optionally specify the attributes of the new thread using a thread attributes object. To do so, your program must:

1. Allocate a thread attributes object and then initialize it by calling the `pthread_attr_init()` routine. (Normally, you will initialize an extern or local variable of the appropriate type.)
2. Set values for the individual attributes of the thread attributes object. (The POSIX standard provides a separate routine for setting each attribute in the thread attributes object.)
3. When ready to create the new thread, pass the address of the thread attributes object as an argument to the `pthread_create()` routine.

After your program creates a thread attributes object, it can be reused for each new thread that the program creates. For the details about creating and deleting a thread attributes object, see the descriptions in Part 2 of the `pthread_attr_init()` and `pthread_attr_destroy()` routines.

Using the thread attributes object, your program can specify these attributes of a new thread:

- Scheduling inheritance
- Scheduling policy
- Scheduling parameters
- Stack size
- Stack location
- Stack guard size
- Contention scope

#### 2.3.2.1 Setting the Inherit Scheduling Attribute

By default, a new thread is created with the scheduling attributes (policy, parameters and contention scope) of its creator. If an attributes object is specified, the scheduling attribute values are ignored. When you want to create a thread with different scheduling attributes, you must set the attribute values, and also set the value of the inheritsched attribute to `PTHREAD_EXPLICIT_SCHED` . You do this by calling the `pthread_attr_setinheritsched()` routine. The default value is `PTHREAD_INHERIT_SCHED` .

Previous | Next | Contents | Index

| privacy and legal statement |
6101PRO_002.HTML