پشتیبانی از ذخیره‌سازی نخ‌محلی

مفسر پایتون پشتیبانی سطح پایین برای ذخیره‌سازی نخ‌محلی (TLS) فراهم می‌کند که پیاده‌سازی بومی TLS در لایه زیرین را پوشش می‌دهد تا از API ذخیره‌سازی نخ‌محلی در سطح پایتون (threading.local) پشتیبانی کند. APIهای سطح C سی‌پایتون مشابه APIهایی هستند که pthreads و ویندوز ارائه می‌دهند: از یک کلید نخ و توابعی برای مرتبط کردن یک مقدار void* به ازای هر نخ استفاده می‌کنند.

وضعیت نخ هنگام فراخوانی این توابع لازم نیست متصل باشد؛ این توابع قفل‌گذاری خودشان را فراهم می‌کنند.

توجه داشته‌باشید که Python.h شامل اعلان API‌های TLS نیست؛ برای استفاده از ذخیره‌سازی نخ‌محلی، باید pythread.h را include کنید.

توجه

هیچ‌یک از این توابع API مدیریت حافظه را برای مقادیر void* انجام نمی‌دهند. شما باید خودتان آن‌ها را تخصیص دهید و آزاد کنید. اگر مقادیر void* اتفاقاً PyObject* باشند، این توابع نیز هیچ عملیات شمارش ارجاعی روی آن‌ها انجام نمی‌دهند.

API ذخیره‌سازی ویژه‌ی نخ (Thread-Specific Storage)

API ذخیره‌سازی اختصاصی نخ (TSS) برای جایگزینی استفاده از API موجود TLS در مفسر سی‌پایتون معرفی شد. این API از نوع جدید Py_tss_t به‌جای int برای نمایش کلیدهای نخ استفاده می‌کند.

اضافه شده در نسخه‌ی 3.7.

همچنین ملاحظه نمائید

«یک 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_tss_t، که در ماژول‌های توسعه‌ای ساخته‌شده با Py_LIMITED_API لازم است؛ جایی که تخصیص ایستای این نوع به دلیل مات بودن پیاده‌سازی آن در زمان ساخت ممکن نیست.

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_alloc() تخصیص یافته است را آزاد می‌کند، پس از آنکه ابتدا PyThread_tss_delete() را برای اطمینان از اینکه هر متغیر نخ‌محلی مرتبطی لغو تخصیص شده باشد فراخوانی کرده است. اگر آرگومان کلید NULL باشد، این یک عملیات بی‌اثر است.

توجه

کلید آزادشده به یک اشاره‌گر معلق تبدیل می‌شود. شما باید کلید را به NULL بازنشانی کنید.

متدها

پارامتر key این توابع نباید NULL باشد. علاوه بر این، رفتار PyThread_tss_set() و PyThread_tss_get() در صورتی تعریف‌نشده است که Py_tss_t داده‌شده با PyThread_tss_create() مقداردهی اولیه نشده باشد.

int PyThread_tss_is_created(Py_tss_t *key)
قسمتی از ABI پایدار از نسخه‌ی 3.7.

اگر Py_tss_t داده‌شده توسط PyThread_tss_create() مقداردهی اولیه شده باشد، مقداری غیر صفر برمی‌گرداند.

int PyThread_tss_create(Py_tss_t *key)
قسمتی از ABI پایدار از نسخه‌ی 3.7.

در صورت موفقیت‌آمیز بودن مقداردهی اولیه‌ی یک کلید TSS، مقدار صفر را برمی‌گرداند. اگر مقداری که آرگومان 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.

مقدار صفر را برای نشان دادن موفقیت در مرتبط کردن یک مقدار void* با کلید TSS در نخ جاری برمی‌گرداند. هر نخ نگاشت متمایزی از کلید به یک مقدار void* دارد.

void *PyThread_tss_get(Py_tss_t *key)
قسمتی از ABI پایدار از نسخه‌ی 3.7.

مقدار void* مرتبط با کلید TSS در نخ جاری را برمی‌گرداند. اگر هیچ مقداری با کلید در نخ جاری مرتبط نباشد، این تابع NULL را برمی‌گرداند.

API‌های قدیمی

منسوخ شده از نسخه‌ی 3.7: این API توسط API ذخیره‌سازی اختصاصی نخ (TSS) جایگزین شده است.

توجه

این نسخه از 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 پایدار.