---
name: "pthread_key_create"
section: "3thr"
platform: "linux"
package: "glibc-doc"
version: "2.1.3-20"
release: "Debian 2.2 (Potato)"
platforms: ["linux"]
url: "https://new.carta.tech/pthread_key_create/3thr"
---

# pthread\_key\_create(3thr)

management of thread-specific data

## NAME

pthread\_key\_create, pthread\_key\_delete, pthread\_setspecific, pthread\_getspecific - management of thread-specific data

## SYNOPSIS

**#include \<pthread.h\>**

**int pthread\_key\_create(pthread\_key\_t \****key***, void (\****destr\_function***) (void \*));**

**int pthread\_key\_delete(pthread\_key\_t** *key***);**

**int pthread\_setspecific(pthread\_key\_t** *key***, const void \****pointer***);**

**void \* pthread\_getspecific(pthread\_key\_t** *key***);**

## DESCRIPTION

Programs often need global or static variables that have different values in different threads. Since threads share one memory space, this cannot be achieved with regular variables. Thread-specific data is the POSIX threads answer to this need.

Each thread possesses a private memory block, the thread-specific data area, or TSD area for short. This area is indexed by TSD keys. The TSD area associates values of type  **void \*** to TSD keys. TSD keys are common to all threads, but the value associated with a given TSD key can be different in each thread.

For concreteness, the TSD areas can be viewed as arrays of  **void \*** pointers, TSD keys as integer indices into these arrays, and the value of a TSD key as the value of the corresponding array element in the calling thread.

When a thread is created, its TSD area initially associates  **NULL** with all keys.

**pthread\_key\_create** allocates a new TSD key. The key is stored in the location pointed to by  *key*. There is a limit of  **PTHREAD\_KEYS\_MAX** on the number of keys allocated at a given time. The value initially associated with the returned key is  **NULL** in all currently executing threads.

The  *destr\_function* argument, if not  **NULL**, specifies a destructor function associated with the key. When a thread terminates via **pthread\_exit** or by cancellation,  *destr\_function* is called with arguments the value associated with the key in that thread. The *destr\_function* is not called if that value is  **NULL**. The order in which destructor functions are called at thread termination time is unspecified.

Before the destructor function is called, the  **NULL** value is associated with the key in the current thread.  A destructor function might, however, re-associate non- **NULL** values to that key or some other key.  To deal with this, if after all the destructors have been called for all non- **NULL** values, there are still some non- **NULL** values with associated destructors, then the process is repeated.  The LinuxThreads implementation stops the process after **PTHREAD\_DESTRUCTOR\_ITERATIONS** iterations, even if some non- **NULL** values with associated descriptors remain.  Other implementations may loop indefinitely.

**pthread\_key\_delete** deallocates a TSD key. It does not check whether non- **NULL** values are associated with that key in the currently executing threads, nor call the destructor function associated with the key.

**pthread\_setspecific** changes the value associated with  *key* in the calling thread, storing the given  *pointer* instead.

**pthread\_getspecific** returns the value currently associated with *key* in the calling thread.

## RETURN VALUE

**pthread\_key\_create**, **pthread\_key\_delete**, and  **pthread\_setspecific** return 0 on success and a non-zero error code on failure. If successful,  **pthread\_key\_create** stores the newly allocated key in the location pointed to by its  *key* argument.

**pthread\_getspecific** returns the value associated with  *key* on success, and  **NULL** on error.

## ERRORS

**pthread\_key\_create** returns the following error code on error:

- **EAGAIN**

  **PTHREAD\_KEYS\_MAX** keys are already allocated

**pthread\_key\_delete** and  **pthread\_setspecific** return the following error code on error:

- **EINVAL**

  *key* is not a valid, allocated TSD key

**pthread\_getspecific** returns  **NULL** if  *key* is not a valid, allocated TSD key.

## AUTHOR

Xavier Leroy \<Xavier.Leroy@inria.fr\>

## SEE ALSO

[pthread\_create(3)](/pthread_create/3.md), [pthread\_exit(3)](/pthread_exit/3.md), [pthread\_testcancel(3)](/pthread_testcancel/3.md).

## EXAMPLE

The following code fragment allocates a thread-specific array of 100 characters, with automatic reclaimation at thread exit:

```

/* Key for the thread-specific buffer */
static pthread_key_t buffer_key;
/* Once-only initialisation of the key */
static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
/* Allocate the thread-specific buffer */
void buffer_alloc(void)
{
  pthread_once(&buffer_key_once, buffer_key_alloc);
  pthread_setspecific(buffer_key, malloc(100));
}
/* Return the thread-specific buffer */
char * get_buffer(void)
{
  return (char *) pthread_getspecific(buffer_key);
}
/* Allocate the key */
static void buffer_key_alloc()
{
  pthread_key_create(&buffer_key, buffer_destroy);
}
/* Free the thread-specific buffer */
static void buffer_destroy(void * buf)
{
  free(buf);
}
```
