آموزش ماژول threading – کلاس Barrier

Please login to bookmark Close

مقدمه

فرض کنید چند ترد دارید که هر کدام یک بخش از یک محاسبه را در «فاز اول» انجام می‌دهند، و فاز دوم باید تنها زمانی شروع شود که همه‌ی تردها فاز اول را تمام کرده باشند – مثل یک مسابقه‌ی دو امدادی که نفر بعدی نباید زودتر از موعد شروع کند. کلاس Barrier دقیقاً برای همین نوع همگام‌سازی طراحی شده است: تعدادی ترد را در یک نقطه نگه می‌دارد تا همه به آن نقطه برسند و سپس همه را همزمان آزاد می‌کند.

ایجاد یک Barrier

import threading

barrier = threading.Barrier(3)

پارامتر اول، parties نام دارد و تعداد تردهایی است که باید wait را صدا بزنند تا همه آزاد شوند. یک پارامتر اختیاری به نام action هم وجود دارد: یک تابع بدون آرگومان که دقیقاً یک بار، توسط یکی از تردها، در لحظه‌ی آزاد شدن همه فراخوانی می‌شود؛ مناسب برای کارهایی مثل چاپ گزارش بین فازها. پارامتر سوم هم timeout نام دارد و مقدار پیش‌فرض زمان انتظار را تعیین می‌کند.

متد wait

هر ترد وقتی به نقطه‌ی همگام‌سازی می‌رسد، متد wait روی شیء barrier را صدا می‌زند. این متد تا زمانی که به تعداد parties ترد آن را صدا نزده باشند، مسدود می‌ماند. به محض رسیدن آخرین ترد، همه‌ی تردهای منتظر همزمان آزاد می‌شوند.

import threading

def worker(barrier, name):
    print(f'{name}: phase 1 started')
    barrier.wait()
    print(f'{name}: phase 2 started')

barrier = threading.Barrier(3)
threads = [threading.Thread(target=worker, args=(barrier, f'worker-{i}')) for i in range(3)]
for t in threads:
    t.start()
for t in threads:
    t.join()

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

وضعیت خراب Barrier و استثنای مربوط به آن

اگر یکی از تردها هنگام انتظار به timeout بخورد، یا متد abort فراخوانی شود، Barrier وارد حالت «خراب» می‌شود. در این حالت، تمام تردهای دیگری که در همان لحظه منتظر بودند یا بعداً وارد می‌شوند، با استثنای threading.BrokenBarrierError مواجه می‌شوند. این رفتار عمدی است: چون قرارداد Barrier این است که «یا همه با هم رد می‌شوند، یا هیچ‌کس»، اگر یک ترد نتواند برسد، ادامه دادن برای بقیه هم منطقی نیست.

import threading
import time

def worker(barrier, name, delay):
    try:
        time.sleep(delay)
        barrier.wait(timeout=1)
        print(f'{name}: passed')
    except threading.BrokenBarrierError:
        print(f'{name}: broken')

barrier = threading.Barrier(3)
delays = [0, 0, 2]
threads = [threading.Thread(target=worker, args=(barrier, f'worker-{i}', delays[i])) for i in range(3)]
for t in threads:
    t.start()
for t in threads:
    t.join()

در این مثال، ترد سوم با تاخیر دو ثانیه‌ای، از timeout یک ثانیه‌ای عبور می‌کند و باعث می‌شود Barrier بشکند؛ به همین دلیل دو ترد دیگر هم استثنا می‌گیرند، نه فقط همان تردی که دیر کرده. برای بازگرداندن Barrier به حالت سالم پس از شکستن، می‌توانید متد reset را روی آن فراخوانی کنید.

ویژگی‌های کاربردی

  • parties: تعداد تردهای لازم برای آزاد شدن.
  • n_waiting: تعداد تردهایی که در حال حاضر منتظرند.
  • broken: مقدار بولی که نشان می‌دهد Barrier در حالت خراب است یا نه.

جمع‌بندی

Barrier برای زمانی مناسب است که چند ترد باید مرحله به مرحله با هم پیش بروند و هیچ تردی نباید زودتر از بقیه وارد مرحله‌ی بعد شود؛ مثلاً در شبیه‌سازی‌های گام‌به‌گام یا الگوریتم‌های موازی که هر مرحله به نتیجه‌ی کامل مرحله‌ی قبل نیاز دارد. برخلاف Lock و Semaphore که برای محافظت از منابع استفاده می‌شوند، Barrier ابزاری برای «همگام‌سازی زمانی» بین تردهاست.

Please login to bookmark Close
پیشرفت شما در «دوره آموزش کانکارنسی در پایتون» (24%)
نظرات

دیدگاهتان را بنویسید

24%
پیشرفت

سرفصل دوره

فهرست مطالب

سرفصل دوره

تمرین

این قسمت تمرین ندارد!

پاسخ تمرین ها

هنوز برای تمرین‌های این قسمت پاسخی ثبت نشده است!

اشتراک گذاری

چرا بهتره از فیلترشکن استفاده کنید؟

من همه ویدئو ها و پادکست های کُدباز رو توی یوتیوب و ساندکلود و پلتفرم هایی آپلود می‌کنم که اغلب فیلتر هستند.

اغلب آموزش‌ها ویدئو و پادکست دارند. پس اگر می‌خواهید از محتوای سایت بیشترین استفاده رو ببرید نیاز به فیلتر شکن دارید.

توجه داشته باشید که برای خرید از فروشگاه بهتره فیلتر شکن رو خاموش کنید.

تنظیمات

انتخاب زبان
تغییر تم