_thread --- API نخ‌بندی سطح پایین


این ماژول، ساختارهای اولیه سطح‌پایینی برای کار با چندین نخ (که به آن‌ها فرایندهای سبک‌وزن <light-weight processes> یا وظایف <tasks> نیز گفته می‌شود) --- چندین نخ کنترل که فضای داده سراسری خود را به اشتراک می‌گذارند. برای همگام‌سازی، قفل‌های ساده‌ای (که به آن‌ها قفل‌های متقابل <mutexes> یا سمافورهای دودویی <binary semaphores> نیز گفته می‌شود) فراهم شده‌اند. ماژول threading، یک API نخ‌بندی سطح‌بالا و آسان‌تر برای استفاده ارائه می‌دهد که بر پایه این ماژول ساخته شده است.

تغییر یافته در نسخه‌ی 3.7: این ماژول پیش‌تر اختیاری بود، اما اکنون همیشه در دسترس است.

این ماژول ثابت‌ها و توابع زیر را تعریف می‌کند:

exception _thread.error

در صورت بروز خطاهای مختص نخ پرتاب می‌شود.

تغییر یافته در نسخه‌ی 3.3: این اکنون مترادفی با RuntimeError توکار است.

_thread.start_new_thread(function, args[, kwargs])

یک نخ جدید آغاز می‌کند و شناسه‌ی آن را برمی‌گرداند. این نخ تابع function را با فهرست آرگومان args (که باید یک تاپل باشد) اجرا می‌کند. آرگومان اختیاری kwargs یک دیکشنری از آرگومان‌های کلیدواژه‌ای را مشخص می‌کند.

هنگامی که تابع بازگشت می‌کند، نخ به‌صورت بی‌صدا خارج می‌شود.

هنگامی که تابع با یک استثنای مدیریت‌نشده پایان می‌یابد، sys.unraisablehook() برای مدیریت استثنا فراخوانی می‌شود. ویژگی object آرگومان قلاب، function است. به‌طور پیش‌فرض، یک ردگیری پشته چاپ می‌شود و سپس نخ خارج می‌شود (اما سایر نخ‌ها به اجرا ادامه می‌دهند).

هنگامی که تابع استثنای SystemExit را پرتاب می‌کند، این استثنا به‌طور بی‌صدا نادیده گرفته می‌شود.

یک رویداد حسابرسی _thread.start_new_thread را با آرگومان‌های function، args و kwargs پرتاب می‌کند.

تغییر یافته در نسخه‌ی 3.8: sys.unraisablehook() اکنون برای رسیدگی به استثناهای رسیدگی‌نشده استفاده می‌شود.

_thread.interrupt_main(signum=signal.SIGINT, /)

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

در صورت داده شدن، signum شماره سیگنالی است که شبیه‌سازی می‌شود. اگر signum داده نشود، signal.SIGINT شبیه‌سازی می‌شود.

اگر سیگنال داده‌شده توسط پایتون مدیریت نشود (روی signal.SIG_DFL یا signal.SIG_IGN تنظیم شده باشد)، این تابع هیچ کاری انجام نمی‌دهد.

تغییر یافته در نسخه‌ی 3.10: آرگومان signum برای سفارشی‌سازی شماره سیگنال افزوده شده است.

توجه

این کار سیگنال متناظر را نشان نمی‌دهد، بلکه فراخوانی هندلر مرتبط را زمان‌بندی می‌کند (در صورت وجود). اگر می‌خواهید واقعاً سیگنال را بفرستید، از signal.raise_signal() استفاده کنید.

_thread.exit()

استثنای SystemExit را پرتاب می‌کند. هنگامی که گرفته نشود، باعث می‌شود نخ به‌صورت خاموش خارج شود.

_thread.allocate_lock()

یک شیء قفل جدید برمی‌گرداند. متدهای قفل‌ها در ادامه توضیح داده شده‌اند. قفل در ابتدا باز است.

_thread.get_ident()

شناسه‌ی نخ جاری را برمی‌گرداند. این یک عدد صحیح غیرصفر است. مقدار آن معنای مستقیمی ندارد؛ این مقدار به‌عنوان یک کوکی جادویی (magic cookie) در نظر گرفته شده است تا برای مثال در اندیس‌گذاری یک دیکشنری از داده‌های مختص نخ استفاده شود. ممکن است شناسه‌های نخ هنگامی که یک نخ خارج می‌شود و نخ دیگری ایجاد می‌شود، دوباره استفاده شوند.

_thread.get_native_id()

شناسه‌ی نخ بومیِ نخ جاری را که یک عدد صحیح است و توسط هسته اختصاص داده شده است، برمی‌گرداند. این یک عدد صحیح نامنفی است. می‌توان از مقدار آن برای شناسایی یکتای این نخ خاص در سراسر سیستم استفاده کرد (تا زمانی که نخ خاتمه یابد؛ پس از آن ممکن است مقدار توسط سیستم‌عامل بازیافت شود).

دسترس‌پذیری: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD, GNU/kFreeBSD.

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

تغییر یافته در نسخه‌ی 3.13: پشتیبانی از GNU/kFreeBSD افزوده شد.

_thread.stack_size([size])

اندازه‌ی پشته‌ی نخ را که هنگام ایجاد نخ‌های جدید استفاده می‌شود، برمی‌گرداند. آرگومان اختیاری size اندازه‌ی پشته‌ای را مشخص می‌کند که برای نخ‌های ایجادشده بعدی استفاده می‌شود، و باید ۰ (استفاده از پیش‌فرض پلتفرم یا پیش‌فرض پیکربندی‌شده) یا یک مقدار عدد صحیح مثبت با حداقل ۳۲٬۷۶۸ (۳۲ KiB) باشد. اگر size مشخص نشده باشد، ۰ استفاده می‌شود. اگر تغییر اندازه‌ی پشته‌ی نخ پشتیبانی نشود، یک RuntimeError پرتاب می‌شود. اگر اندازه‌ی پشته‌ی مشخص‌شده نامعتبر باشد، یک ValueError پرتاب می‌شود و اندازه‌ی پشته بدون تغییر باقی می‌ماند. در حال حاضر ۳۲ KiB حداقل مقدار اندازه‌ی پشته‌ی پشتیبانی‌شده برای تضمین فضای پشته‌ی کافی برای خود مفسر است. توجه داشته باشید که برخی پلتفرم‌ها ممکن است محدودیت‌های خاصی برای مقادیر اندازه‌ی پشته داشته باشند، مانند نیاز به حداقل اندازه‌ی پشته > ۳۲ KiB یا نیاز به تخصیص به‌صورت مضرب‌هایی از اندازه‌ی صفحه‌ی حافظه‌ی سیستم — برای اطلاعات بیشتر باید به مستندات پلتفرم مراجعه شود (صفحه‌های ۴ KiB رایج هستند؛ استفاده از مضرب‌های ۴۰۹۶ برای اندازه‌ی پشته، روش پیشنهادی در نبود اطلاعات خاص‌تر است).

دسترس‌پذیری: Windows, pthreads.

سکوهای یونیکسی با پشتیبانی از نخ‌های POSIX.

_thread.TIMEOUT_MAX

حداکثر مقدار مجاز برای پارامتر timeout در Lock.acquire. تعیین مهلت زمانی بزرگ‌تر از این مقدار باعث پرتاب OverflowError می‌شود.

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

class _thread.LockType

این نوع اشیای قفل است.

اشیای قفل دارای متدهای زیر هستند:

acquire(blocking=True, timeout=-1)

بدون هیچ آرگومان اختیاری، این متد قفل را بدون شرط کسب می‌کند و در صورت لزوم منتظر می‌ماند تا توسط نخ دیگری آزاد شود (فقط یک نخ در هر زمان می‌تواند یک قفل را کسب کند — دلیل وجودی آن‌ها همین است).

اگر آرگومان blocking موجود باشد، رفتار به مقدار آن بستگی دارد: اگر مقدار آن نادرست باشد، قفل فقط در صورتی به دست می‌آید که بتوان آن را فوراً و بدون انتظار به دست آورد، در حالی که اگر مقدار آن درست باشد، قفل بی‌قیدوشرط مانند بالا به دست می‌آید.

اگر آرگومان timeout ممیز شناور موجود و مثبت باشد، حداکثر مهلت زمانی بر حسب ثانیه را پیش از بازگشت مشخص می‌کند. آرگومان timeout منفی، یک انتظار نامحدود را مشخص می‌کند. اگر blocking نادرست باشد، نمی‌توانید timeout را مشخص کنید.

در صورت کسب موفق قفل، مقدار بازگشتی True و در غیر این صورت False است.

تغییر یافته در نسخه‌ی 3.2: پارامتر timeout جدید است.

تغییر یافته در نسخه‌ی 3.2: اکنون می‌توان کسب قفل را در POSIX با سیگنال‌ها قطع کرد.

تغییر یافته در نسخه‌ی 3.14: اکنون در ویندوز، به دست آوردن قفل می‌تواند با سیگنال‌ها قطع شود.

release()

قفل را آزاد می‌کند. قفل باید پیش‌تر کسب شده باشد، اما نه لزوماً توسط همان نخ.

locked()

وضعیت قفل را برمی‌گرداند: اگر توسط نخی گرفته شده باشد True و در غیر این صورت False.

علاوه بر این متدها، می‌توان از اشیای قفل از طریق دستور with نیز استفاده کرد، برای مثال:

import _thread

a_lock = _thread.allocate_lock()

with a_lock:
    print("a_lock is locked while this executes")

ملاحظات:

  • وقفه‌ها همیشه به نخ اصلی تحویل داده می‌شوند (استثنای KeyboardInterrupt توسط آن نخ دریافت خواهد شد.)

  • فراخوانی sys.exit() یا پرتاب استثنای SystemExit معادل فراخوانی _thread.exit() است.

  • هنگامی که نخ اصلی خارج می‌شود، این که سایر نخ‌ها زنده بمانند یا خیر، توسط سیستم تعیین می‌شود. در بیشتر سیستم‌ها، آن‌ها بدون اجرای بندهای try ... finally یا اجرای مخرب‌های شیء کشته می‌شوند.