Python

스레드 로컬 저장소 지원

파이썬 인터프리터는 파이썬 수준의 스레드 로컬 저장소 API(threading.local)를 지원하기 위해 하부 네이티브 TLS 구현을 래핑한 저수준의 스레드 로컬 저장소(TLS) 지원을 제공합니다. CPython C 레벨 API는 pthreads 및 Windows에서 제공하는 것과 유사하며, 스레드 키와 함수를 사용하여 각 스레드에 void* 값을 할당합니다.

이 함수들을 호출할 때 thread state 가 반드시 attached 상태일 필요는 없습니다. 이 기능들은 자체적으로 잠금(locking)을 제공합니다.

Python.h 에는 TLS API 선언이 포함되어 있지 않으므로, 스레드 로컬 저장소를 사용하려면 pythread.h 를 포함해야 합니다.

참고

이 API 함수 중 어느 것도 void* 값에 대한 메모리 관리를 대행하지 않습니다. 직접 할당 및 해제를 수행해야 합니다. 만약 void* 값이 PyObject* 인 경우에도 이 함수들은 참조 횟수(refcount) 연산을 수행하지 않습니다.

스레드별 저장소 API

스레드별 저장소(TSS) API는 CPython 인터프리터 내의 기존 TLS API 사용을 대체하기 위해 도입되었습니다. 이 API는 스레드 키를 표현하기 위해 int 대신 새로운 타입인 Py_tss_t 를 사용합니다.

Added in version 3.7.

더 보기

“CPython의 스레드 로컬 저장을 위한 새로운 C-API” (PEP 539)

type Py_tss_t

이 데이터 구조는 스레드 키의 상태를 나타내며, 그 정의는 하부 TLS 구현에 따라 달라질 수 있습니다. 또한 이 구조체는 키의 초기화 상태를 나타내는 내부 필드를 포함합니다. 이 구조체에는 공개 멤버가 없습니다.

Py_LIMITED_API 가 정의되지 않은 경우, Py_tss_NEEDS_INIT 를 통한 이 타입의 정적 할당이 허용됩니다.

Py_tss_NEEDS_INIT

이 매크로는 Py_tss_t 변수용 초기화자로 확장됩니다. 이 매크로는 Py_LIMITED_API 환경에서는 정의되지 않음에 유의하십시오.

동적 할당

Py_LIMITED_API 로 빌드된 확장 모듈에서 필요한 Py_tss_t 의 동적 할당입니다. 빌드 시점에 구현이 불투명하여 이 타입의 정적 할당이 불가능한 경우에 사용됩니다.

Py_tss_t *PyThread_tss_alloc()
…의 일부 안정 ABI 버전 3.7 이후로.

Py_tss_NEEDS_INIT 으로 초기화된 값과 동일한 상태의 값을 반환하거나, 동적 할당 실패 시 NULL 을 반환합니다.

void PyThread_tss_free(Py_tss_t *key)
…의 일부 안정 ABI 버전 3.7 이후로.

관련된 모든 스레드 로컬이 해제되었는지 확인하기 위해 먼저 PyThread_tss_delete() 를 호출한 후, PyThread_tss_alloc() 으로 할당된 key 를 해제합니다. key 인자가 NULL 인 경우 아무 작업도 수행하지 않습니다.

참고

해제된 키는 댕글링 포인터가 됩니다. 키를 NULL 로 재설정해야 합니다.

메서드

이 함수들의 매개변수 keyNULL 이 아니어야 합니다. 또한, 주어진 Py_tss_tPyThread_tss_create() 로 초기화되지 않은 경우 PyThread_tss_set()PyThread_tss_get() 의 동작은 정의되지 않습니다.

int PyThread_tss_is_created(Py_tss_t *key)
…의 일부 안정 ABI 버전 3.7 이후로.

주어진 Py_tss_tPyThread_tss_create() 로 초기화된 경우 0이 아닌 값을 반환합니다.

int PyThread_tss_create(Py_tss_t *key)
…의 일부 안정 ABI 버전 3.7 이후로.

TSS 키 초기화에 성공하면 0을 반환합니다. key 인자가 가리키는 값이 Py_tss_NEEDS_INIT 으로 초기화되지 않은 경우 동작이 정의되지 않습니다. 이 함수는 동일한 키에 대해 반복적으로 호출될 수 있으며, 이미 초기화된 키에 대해 호출하면 아무 작업도 수행하지 않고 즉시 성공을 반환합니다.

void PyThread_tss_delete(Py_tss_t *key)
…의 일부 안정 ABI 버전 3.7 이후로.

TSS 키를 파괴하여 모든 스레드에서 해당 키와 관련된 값을 잊게 하고, 키의 초기화 상태를 ‘초기화되지 않음’으로 변경합니다. 파괴된 키는 PyThread_tss_create() 로 다시 초기화할 수 있습니다. 이 함수는 동일한 키에 대해 반복적으로 호출될 수 있으며, 이미 파괴된 키에 대해 호출하면 아무 작업도 수행하지 않습니다.

int PyThread_tss_set(Py_tss_t *key, void *value)
…의 일부 안정 ABI 버전 3.7 이후로.

현재 스레드에서 TSS 키와 void* 값을 성공적으로 연결하면 0을 반환합니다. 각 스레드는 키에 대한 고유한 void* 값 매핑을 가집니다.

void *PyThread_tss_get(Py_tss_t *key)
…의 일부 안정 ABI 버전 3.7 이후로.

현재 스레드에서 TSS 키와 연결된 void* 값을 반환합니다. 현재 스레드에 해당 키와 연결된 값이 없으면 NULL 을 반환합니다.

레거시 API

버전 3.7부터 폐지됨: 이 API는 스레드별 저장소 (TSS) API 로 대체되었습니다.

참고

이 버전의 API는 네이티브 TLS 키가 int 로 안전하게 캐스팅될 수 없는 방식으로 정의된 플랫폼을 지원하지 않습니다. 해당 플랫폼에서 PyThread_create_key() 는 즉시 실패 상태를 반환하며, 다른 모든 TLS 함수들은 아무 작업도 수행하지 않습니다.

위에 언급된 호환성 문제로 인해, 새 코드에서는 이 버전의 API를 사용해서는 안 됩니다.

int PyThread_create_key()
…의 일부 안정 ABI.
void PyThread_delete_key(int key)
…의 일부 안정 ABI.
int PyThread_set_key_value(int key, void *value)
…의 일부 안정 ABI.
void *PyThread_get_key_value(int key)
…의 일부 안정 ABI.
void PyThread_delete_key_value(int key)
…의 일부 안정 ABI.
void PyThread_ReInitTLS()
…의 일부 안정 ABI.