# چند نخی Multi Threading

چند نخی یا multi treading به معنای توانایی یک برنامه در تقسیم شدن به چند تار (زیر برنامه) است که می‌توانند جداگانه و درعین‌حال هم‌زمان توسط رایانه اجرا شوند به‌این‌ترتیب نرم‌افزار تعامل بهتری با کاربر خواهد داشت. نخ‌ها در حقیقت تکه کدهایی هستند که در برنامه به‌صورت موازی اجرا خواهند شد و به برنامه‌نویس این امکان را می‌دهند چندین کار را به‌صورت هم‌زمان در برنامه خود انجام دهد.\
&#x20;نکته قابل‌توجه در این نوع از برنامه‌نویسی این است که چند نخی ارتباط مستقیم با سیستم‌عامل شما دارد به این معنا که سیستم‌عامل شما باید قابلیت اجرای برنامه‌های چند نخی را داشته باشد برای مثال ویندوز و اکثر سیستم‌عامل‌های خانواده لینوکس و... این توانایی رادارند.\
&#x20;اجرا کردن یک نخ در پایتون مانند اجرا کردن یک برنامه به‌وسیله کد است با این تفاوت که مزیت‌های زیر را نیز خواهد داشت:

* • چندین نخ در داخل یک نخ می‌توانند داده‌ها و ارتباطات خود را خیلی راحت‌تر از زمانی که هرکدام از آن‌ها به‌تنهایی یک پردازش محسوب می‌شوند بین یکدیگر به اشتراک بگذارند.
* • گاهی اوقات نخ‌ها به‌صورت پردازش‌های light-weight فراخوانی می‌شوند بنابراین آن‌ها به حافظه سربار (memory overhead) زیادی احتیاج نخواهند داشت که این امر باعث بالا رفتن کیفیت کد برنامه‌نویس می‌شود.

اولین ماژولی که برنامه‌نویس برای تعریف یک نخ باید با آن آشنا باشد ماژول thread است که امکانات سطح پائینی را برای کار کردن با نخ‌ها در اختیار برنامه‌نویس قرار می‌دهد برای اینکه برنامه‌نویس یک نخ را بسازد لازم است تا از متد start\_new\_thread به شکل زیر استفاده نماید:

```python
thread.start_new_thread (function, args[, kwargs])
```

که ورودی‌های آن نام تابع موردنظر برنامه‌نویس که می‌خواهد در نخ قرار بگیرد و آرگومان‌های ورودی آن‌که به‌صورت یک تاپل می‌باشند خواهد بود به مثال زیر توجه نمایید:

```python
import thread
import time

# Define a function for the thread
def print_time(threadName, delay):
 count = 0
 while count < 5:
 time.sleep(delay)
 count += 1
 print "%s: %s" % (threadName, time.ctime(time.time()))

# Create two threads as follows
try:
 thread.start_new_thread(print_time, ("Thread-1", 2,))
 thread.start_new_thread(print_time, ("Thread-2", 4,))
except:
 print "Error: unable to start thread"

while 1:
 pass

>>>
Thread-1: Mon Jan 24 13:14:50 2011
Thread-2: Mon Jan 24 13:14:52 2011
Thread-1: Mon Jan 24 13:14:52 2011
Thread-1: Mon Jan 24 13:14:54 2011
Thread-2: Mon Jan 24 13:14:56 2011
Thread-1: Mon Jan 24 13:14:56 2011
Thread-1: Mon Jan 24 13:14:58 2011
Thread-2: Mon Jan 24 13:15:00 2011
Thread-2: Mon Jan 24 13:15:04 2011
Thread-2: Mon Jan 24 13:15:08 2011

```

همان‌طور که در مثال قبل مشاهده نمودید دو نخ بانام‌های thread-1 و thread-2 ایجاد کردیم که اولی بعد از 2 ثانیه و دومی بعد از 4 ثانیه تأخیر اقدام به چاپ تاریخ می‌کنند و هرکدام این کار را 5 بار تکرار می‌کنند البته ماژول thread ماژول بسیار خوبی برای کار با نخ‌هاست ولی در تعداد نخ‌هایی که می‌تواند با آن‌ها کار کند محدودیت دارد در زیر چند تابع از این ماژول را معرفی می‌نماییم.

|                                                                                    توضیح |      نام تابع     |
| ---------------------------------------------------------------------------------------: | :---------------: |
|                                                       خطاهای مربوط به نخ را برمی‌گرداند. |      Error()      |
|                                                                  یک نوع از شیء lock است. |     LockType()    |
|    یک وقفه در نخ اصلی ایجاد می‌نماید تا زیر نخ‌ها بتوانند از یک تابع خاص استفاده نمایند. | interrupt\_main() |
|       باعث ایجاد خطای systemexit می‌شود و اگر نتواند آن را پیدا کند نخ را متوقف می‌سازد. |       exit()      |
|                                                    یکشی جدید از نوع lock را برمی‌گرداند. |  allocate\_lock() |
| هویت نخ‌هایی که در حال حاضر در حال اجرا هستند را برمی‌گرداند که به‌صورت یک عدد مثبت است. |    get\_ident()   |

ماژول دیگری که در این زمینه وجود دارد ماژول threading است که دسترسی سطح بالاتری را نسبت به ماژول thread در اختیار برنامه‌نویس قرار می‌دهد همچنین توابع این ماژول توانایی بیشتری در مقابل ماژول thread برای کنترل نخ‌ها در اختیار برنامه‌نویس قرار می‌دهد. در ادامه با تعدادی از توابع این ماژول بیشتر آشنا خواهیم شد.

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      توضیح |                    نام تابع                    |
| -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------: |
|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        تعداد نخ‌هایی را که در حال حاضر فعال می‌باشند را برمی‌گردانند که این عدد برابر است با تعداد فهرستی که تابع enumerate() برمی‌گرداند. |   <p>active\_count()</p><p>activeCount()</p>   |
|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     یک تابع تولیدکننده که یک متغیر شی‌ء از نوع condition را برمی‌گرداند. یک متغیر condition به یک یا چندین نخ این امکان را می‌دهد تا منتظر بمانند تا زمانی که توسط نخ دیگری فراخوانی شوند. |                   Condition()                  |
|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                یکشی از Thread فعلی را برمی‌گرداند که به نخی که این تابع را صدا کرده است. اگر نخ فراخوانی کننده به‌صورت مستقیم با ماژول threading ساخته نشده باشد یکشی مجازی از آن نخ (dummy thread) که ازنظر دسترسی به توابع محدود گشته بازگردانده می‌شود. | <p>current\_thread()</p><p>currentThread()</p> |
|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          یک لیست از تمامی اشیائی از نوع thread که در حال حاضر فعال هستند را برمی‌گرداند. این لیست شامل نخ‌های کمکی نخ‌های مجازی که توسط current\_thread ساخته‌شده‌اند و همچنین نخ‌های اصلی است ولی شامل نخ‌هایی که کارشان به پایان رسیده یا هنوز آغاز به کارنکرده‌اند است. |                   Enumerate()                  |
|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   یک تابع تولیدکننده که یکشی جدید از نوع event را به ما برمی‌گرداند. هر رویداد یک پرچم را مدیریت می‌کند که می‌تواند با استفاده از متد set() مقدارش true شود و با متد clear() مقدارش را flase کرد همچنین متد wait() نخ را متوقف می‌کند و صبر می‌کند تا مقدار پرچم true شود. |                     Event()                    |
|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       یک تابع تولیدکننده که یکشی ابتدایی از نوع lock را برمی‌گرداند. وقتی یک نخ آن را در دست می‌گیرد متعاقباً متوقف خواهد شد تا زمانی که دوباره آزاد شود و ای آزادسازی توسط هر نخ دیگری می‌تواند محقق شود. |                     Lock()                     |
|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             یک تابع تولیدکننده که یکشی جدید از نوع reentrant lock برمی‌گرداند. این شی‌ء باید توسط نخی که آن را ایجاد کرده است آزاد شود. زمانی که یک نخ چنین شیئی را ایجاد می‌کند شاید نخ مشابهی همین شی‌ء را ایجاد کند بدون اینکه متوقف‌شده باشد بنابراین هر نخ به ازای هر بار ایجاد این شیء باید یک‌بار آن را آزاد نماید. |                     RLock()                    |
| یک تابع تولیدکننده که یک شیء جدید از نوع semaphore را برمی‌گرداند. یک semaphore عددی را مدیریت می‌کند که نشان‌دهنده تعداد فراخوانی کلاس release() است. همچنین با هر بار فراخوانی acquire() این عدد کاهش پیدا می‌نماید و با تولید هر مقدار جدیدی این عدد افزایش می‌یابد. همچنین اگر لازم باشد acquire() متوقف می‌شود تا زمانی که عدد semaphore منفی نباشد. مقدار پیش‌فرض value عدد یک است. (در علوم رایانه سمافور به متغیری اطلاق می‌شود که در محیط‌های همروند برای کنترل دسترسی فرایندها به منابع مشترک به کار می‌رود. سمافور می‌تواند به دو صورت دودویی) که تنها دو مقدار صحیح و غلط را دارا است (و یا شمارنده اعداد صحیح باشد. از سمافور برای جلوگیری از ایجاد مسئلهٔ مسابقه میان فرایندها استفاده می‌گردد. به‌این‌ترتیب، اطمینان حاصل می‌شود که در هرلحظه تنها یک فرایند به منبع مشترک دسترسی داشته و می‌تواند از آن بخواند یا بنویسد.) |               Semaphore(\[value])              |
|                                                                                                                                                                                                                                                                                                                                                                                                       یک تابع تولیدکننده که یک شیء جدید از نوع bounded semaphore را برمی‌گرداند. یک bounded semaphore عدد سمافور را بررسی می‌کند تا اطمینان حاصل کند که از مقدار اصلی‌اش کمتر نیست. اگر این اتفاق بیفتد آنگاه خطای valuError رخ خواهد داد. بیشتر اوقات سمافورها برای محافظت کردن از منابعی با ظرفیت محدود دسترسی استفاده می‌شوند. تعدد استفاده از سمافور در برنامه‌ها ممکن است در برنامه ایجاد مشکل نماید. مقدار پیش‌فرض value عدد یک است. |           BoundedSemaphore(\[value])           |
|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               یک تابع را به‌عنوان تعقیب‌کننده برای تمامی نخ‌هایی که از آن ماژول threading ساخته‌شده‌اند مستقر می‌نماید. در حقیقت این تابع هر نخ را قبل از اینکه متد run برایش اجرا شود به تابع sys.setrace() ارجاع می‌دهد. |                 settrace(func)                 |
|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       یک تابع را به‌عنوان profile function برای تمامی نخ‌هایی که از آن ماژول threading ساخته‌شده‌اند مستقر می‌نماید. در حقیقت این تابع هر نخ را قبل از اینکه متد run برایش اجرا شود به تابع sys.setprofile() ارجاع می‌دهد. |                setprofile(func)                |
|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |              stack\_size(\[size])              |

در ادامه به بررسی کلاس‌های این ماژول خواهیم پرداخت

|                                                                                                                                                                                                                               توضیح | نام کلاس |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------: |
| وظیفه این کلاس نمایش داده نخ محلی (thread-local data) است. داده نخ محلی داده‌ای است که مقادیر آن مخصوص به آن نخ است. برای مدیریت داده نخ محلی کافی ست یک نمونه از این کلاس بسازید و مقادیر موردنظر خود را در آن‌ها مقداردهی نمایید. |   local  |
|                                                                                                                          این کلاس یک نخ از کنترل را نمایش می‌دهد. این کلاس می‌تواند به‌طور امن در حالتی محدود به زیر کلاس مشتق شود. |  Thread  |
|                                                                                                                                                                            نخی که یک تابع را بعد از یک بازه زمانی مشخص اجرا می‌کند. |   Timer  |

## شیء Thread

این کلاس فعالیت‌هایی را که در حال اجرا در یک نخ کنترلی مجزا هستند را نمایش می‌دهد. دو راه برای تشخیص فعالیت‌ها وجود دارد، شناسایی اشیاء قابل صدا شدن در سازنده (constructor) و یا لغو (override) کردن متد run در یک زیر کلاس. هیچ متد دیگری (سازنده‌ها در این مورد استثنا می‌باشند) نباید در زیر کلاس‌ها لغو شوند. به زبان دیگر تنها سازنده و متد run را می‌توان در این کلاس لغو (override) نمود.\
&#x20;زمانی که یک شیء از این کلاس ساخته شد، با فراخوانی متد start فعالیت خود را آغاز می‌نماید. از زمانی که نخ‌ها فعالیت خود را آغاز نمودند وضعیتشان به‌صورت alive درمی‌آید؛ و زمانی که کار متد run به پایان می‌رسد این وضعیت را از دست می‌دهند. از متد is\_alive() می‌توان برای بررسی وضعیت alive بودن یک نخ استفاده نمود.\
&#x20;همچنین نخ‌های دیگر می‌توانند متد join همدیگر را فراخوانی نمایند. این کار باعث می‌شود تا نخی که متدش فراخوانی شده منتظر بماند تا زمانی که نخ فراخوانی کننده به پایان برسد.\
&#x20;هر نخ دارای نامی است که برنامه‌نویس می‌تواند آن را به سازنده ارسال نماید و از طریق صفت name به آن دسترسی داشته باشد یا آن را تغییر دهد. همچنین یک نخ می‌تواند به‌عنوان یک نخ کمکی (daemon thread) علامت‌گذاری شود این بدان معناست که برنامه پایتون زمانی که به پایان می‌رسد تمام نخ‌های کمکی به‌صورت خودکار پایان می‌یابد. با استفاده از خاصیت daemon می‌توان یک نخ را به‌عنوان نخ کمکی علامت‌گذاری نمود. به‌طورکلی متدهای این کلاس را در جدول زیر مشاهده می‌نمایید:

|                                                                                                                                                                توضیح |                     نام متد                     |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------: |
|                                         باعث آغاز فعالیت نخ می‌شود. این متد درصورتی‌که بیش از یک‌بار در هر شیء فراخوانی شود خطای RuntimeException را ایجاد می‌نماید. |                     start()                     |
|                                                                                                                                   این متد فعالیت نخ را نمایش می‌دهد. |                      run()                      |
|                                                                                                                                صبر می‌نماید تا کار نخ به پایان برسد. |                 join(\[timeout])                |
| یک مقدار از نوع رشته‌ای که تنها هدف یک نخ را مشخص می‌نماید و ازلحاظ معنایی هیچ کاربردی ندارد. همچنین این امکان وجود دارد که چندین نخ مختلف از یک نام استفاده نمایند. |   <p>getName()</p><p>setName()</p><p>name</p>   |
|                                  شناسه هر نخ (thread identifier) یک مقدار عددی بزرگ‌تر از صفر است که تا زمانی که با متد start آغاز به کارنکرده باشد مقدارش None است. |                      ident                      |
|                                                                                                                   وضعیت یک نخ را در رابطه با زنده‌بودنش نشان می‌دهد. |        <p>is\_alive()</p><p>isAlive()</p>       |
|                                                                                                     یک مقدار بولی که نخ را به‌عنوان یک نخ کمکی علامت‌گذاری می‌نماید. | <p>isDaemon()</p><p>setDaemon()</p><p>demon</p> |

## شیء Lock

یک Lock اصلی یک هماهنگ ساز (synchronization) اولیه است و این بدان معناست که در زمان قفل شدن یک نخ، قابل مدیریت با نخ منفرد دیگری نخواهد بود.\
&#x20;در حال حاضر این شی‌ء در پایتون پایین‌ترین سطح در هماهنگ‌سازی اولیه که به‌طور مستقیم توسط ماژول توسعه‌یافته thread اجرا می‌شود را اجرا می‌نماید.\
&#x20;این شی‌ء دو متد اصلی دارد که در زیر درباره آن‌ها توضیح خواهیم داد

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 توضیح |     نام متد    |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------: |
| <p>یک نخ را متوقف می‌سازد یا به‌اصطلاح قفل می‌نماید.<br> زمانی که این متد بدون آرگومان ورودی صدا زده می‌شود نخ متوقف می‌شود تا زمانی که نخ بار دیگر راه‌اندازی شود و مقدار true را برمی‌گرداند.<br> زمانی که این متد با آرگومان ورودی با مقدار true صدا زده شود نخ متوقف می‌شود و مقدار true برگردانده می‌شود.<br> زمانی که این متد با آرگومانی با مقدار false صدا زده شود نخ متوقف نمی‌شود. اگر این متد بدون آرگومان ورودی صدا زده شود مقدار false را برمی‌گرداند در غیر این صورت نخ را متوقف نموده و مقدار true را برمی‌گرداند.</p> | Lock.acquire() |
|                                                                                                                                                                                                                                                                                                                                                                                        <p>یک نخ متوقف‌شده را آزاد می‌نماید. اگر نخ شما در حالت lock نباشد این متد هیچ کاری انجام نمی‌دهد. <br>این متد هیچ مقداری را برنمی‌گرداند.</p> | Lock.release() |

## شیء Rlock

یک قفل بازگشتی (reentrant) که این قابلیت را دارد که چندین بار فراخوانی شود و ازنظر عملکرد تفاوتی با قفل معمولی ندارد. اگر بخواهیم دقیق‌تر شویم، این شی‌ء برای رساندن مفهوم مالکیت داشتن بر نخ‌ها در سطوح بازگشتی مورداستفاده قرار می‌گیرد.

## شیء Condition

مقدار این شیء همیشه در ارتباط با بعضی از انواع lock ها می‌باشند؛ که می‌توان آن را برایش ارسال یا به‌صورت پیش‌فرض برایش تنظیم نمود. این شیء دو متد دارد که به‌وسیله متدهای متناظرشان در شیء lock صدا زده می‌شوند. همچنین متدهای دیگری نیز دارند که در ادامه به آن‌ها اشاره خواهیم نمود:

|                                                                                                                                                                                                    توضیح |                 نام متد                |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------: |
|                             زیربنای یک قفل را مشخص می‌نماید. این متد به‌وسیله متد متناظرش در زیربنای یک قفل فراخوانی می‌شود. مقداری که این متغیر برمی‌گرداند همان مقداری است که متد متناظرش برمی‌گرداند. |                acquire()               |
|                                                                     زیربنای یک قفل را آزاد می‌نماید. این متد به‌وسیله متد متناظرش در زیربنای یک قفل فراخوانی می‌شود. این متد هیچ مقداری را برنمی‌گرداند. |                release()               |
| نخ به حالت انتظار می‌رود تا زمانی که خطایی رخ دهد یا زمان در نظر گرفته‌شده به پایان برسد. اگر نخی که این متد را فراخوانی نموده در زمان فراخوانی در حالت قفل نباشد خطای runtimeerror به وقوع خواهد پیوست. |            wait(\[timeout])            |
|                                                   یک نخ را از حالت انتظار بیدار می‌نماید. اگر نخی که این متد را فراخوانی نموده در زمان فراخوانی در حالت قفل نباشد خطای runtimeerror به وقوع خواهد پیوست. |                notify()                |
|                 تمامی نخ‌هایی را که در حالت انتظار به سر می‌برند را بیدار می‌نماید. عملکرد این متد دقیقاً مانند متد notify است با این تفاوت که برای تمامی نخ‌هایی که در وضعیت انتظار هستند اعمال می‌شود. | <p>notify\_all()</p><p>notifyAll()</p> |

## شیء Semaphore

این شیء یکی از قدیمی‌ترین شکل‌های هندسی در هماهنگ‌سازی تاریخچه علم کامپیوتر است. کار اصلی یک سمافور مدیریت شمارنده‌های داخلی می‌باشند که با هر بار فراخوانی متد acquire کاهش و با هر بار فراخوانی متد release افزایش می‌یابند. مقدار این شمارنده هرگز نباید کمتر از صفر شود زمانی که مقدار یک شمارنده صفر باشد و متد acquire فراخوانی شود سمافور اجازه start شدن را به نخ نمی‌دهد و به‌اصطلاح آن را قفل می‌نماید و منتظر می‌ماند تا متد relase فراخوانی شود. در حقیقت سمافورها برای کنترل دسترسی‌ها مورداستفاده قرار می‌گیرند.

|                                                                                                                                                                                                                                       توضیح |           نام متد           |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------: |
|                                                                                                                            آرگومان ورودی این کلاس عددی است که به شمارنده سمافور اختصاص داده می‌شود. به‌صورت پیش‌فرض این عدد برابر با 1 است. | class threading.Semaphore() |
| یک سمافور را ایجاد می‌نماید. درصورتی‌که مقدار شمارنده سمافور بزرگ‌تر از صفر باشد تنها یک مقدار از آن کم می‌نماید در غیر این صورت پردازش را به حالت انتظار می‌برد تا زمانی که پردازه دیگری کارش به پایان برسد و مقدار شمارنده را افزایش دهد. |          acquire()          |
|                                                                 مقدار شمارنده داخلی سمافور را یک واحد افزایش می‌دهد. اگر مقدار شمارنده سمافور صفر باشد و پردازشی در حالت انتظار باشد آن پردازش را نیز از حال انتظار به حالت اجرا درمی‌آورد. |          release()          |

## شیء Event

یکی از ساده‌ترین راه¬های ارتباط برقرار کردن بین نخ‌ها است.\
&#x20;این شیء پرچم‌های (flag) داخلی را مدیریت می‌نماید به این صورت که با فراخوانی متد set مقدار آن‌ها را true و با فراخوانی متد clear مقدار آن‌ها را با false مقداردهی می‌نماید. در ادامه به بررسی متدهای این شیء خواهیم پرداخت:

|                                                                                                                           توضیح |             نام متد            |
| ------------------------------------------------------------------------------------------------------------------------------: | :----------------------------: |
|                                                                                                یک پرچم داخلی را ایجاد می‌نماید. |      class threading.Event     |
|                                                      اگر مقدار پرچم موردنظر true باشد این متد مقدار true را به شما برمی‌گرداند. | <p>is\_set()</p><p>isSet()</p> |
|                                                                                  مقدار یک پرچم داخلی را معادل true قرار می‌دهد. |              set()             |
|                                                                                 مقدار یک پرچم داخلی را معادل false قرار می‌دهد. |             clear()            |
| یک نخ را متوقف می‌نماید تا زمانی که مقدار پرچم با true مقداردهی شود یا زمانی که در آرگومان ورودی مقداردهی گردیده به پایان برسد. |        wait(\[timeout])        |

## شیء Timer

این کلاس یک عمل مشخص را بعد از مدت‌زمانی مشخص‌شده انجام می‌دهد. در حقیقت این کلاس یک زیر کلاس (subclass) از کلاس thread است. این کلاس با فراخوانی متد start شروع به کار می‌نماید و با فراخوانی متد cancle به کار خود پایان می‌دهد. به مثال زیر توجه نمایید:

```python
import threading

def hello():
    print "hello, world"

t = threading.Timer(5.0, hello)
t.start() # after 5 seconds, "hello, world" will be printed

>>>hello, world

```

همان‌طور که در مثال بالا مشاهده نمودید تکه کد نوشته‌شده بعد از 5 ثانیه اقدام به اجرای تابع hello می‌نماید.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://iarash.gitbook.io/payton-based-on-documentation/fsl-shshm/chnd-nkhy-multi-threading.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
