آموزش ماژول multiprocessing – کلاس Lock

Please login to bookmark Close

به تکه کد زیر توجه کنید:

import multiprocessing

# Shared resource
shared_counter = multiprocessing.Value('i', 0)

def increment_counter(shared_counter):
    for _ in range(100000):
        shared_counter.value += 1

if __name__ == '__main__':
    # Create multiple processes
    processes = []
    for _ in range(5):
        p = multiprocessing.Process(target=increment_counter, args=(shared_counter, ))
        p.start()
        processes.append(p)

    # Wait for all processes to finish
    for p in processes:
        p.join()

    # Print the final value of the shared counter
    print("Final value of the counter:", shared_counter.value)

توضیح کد بالا:

  • خط ۴: یک منبع مشترک درست کرده ایم تا بتوانیم بین چندین process از آن استفاده کنیم.
  • خط ۶ تا ۸: یک تابع تعریف کرده‌ایم که یک واحد به مقدار یک منبع مشترک اضافه می‌کند. در نهایت هر بار که این تابع کامل اجرا شود مقدار منبع مشترک باید صد هزار واحد اضافه شده باشد.
  • خط ۱۳ تا ۱۶: ۵ پردازش ایجاد و start کرده‌ایم و آن‌ها را به یک لیست نیز اضافه کرده ایم تا بعدا راحت تر join کنیم.

انتظار می‌رود که خروجی برابر 500000 باشد اما مقداری کمتر است و هر بار که این تکه کد را اجرا کنید مقدار متفاوتی خواهید داشت.

به این مشکل race condition یا شرایط رقابتی می‌گویند.

برای حل این مشکل باید از کلاس Lock از ماژول multiprocessing استفاده کرد. بدین منظور با کمی تغییر در کد بالا به کد زیر خواهیم رسید که این مشکل را ندارد.

import multiprocessing

lock = multiprocessing.Lock()

# Shared resource
shared_counter = multiprocessing.Value('i', 0)

def increment_counter(shared_counter, lock):
    lock.acquire()
    for _ in range(100000):
        shared_counter.value += 1
    lock.release()

if __name__ == '__main__':
    # Create multiple processes
    processes = []
    for _ in range(5):
        p = multiprocessing.Process(target=increment_counter, args=(shared_counter, lock))
        p.start()
        processes.append(p)

    # Wait for all processes to finish
    for p in processes:
        p.join()

    # Print the final value of the shared counter
    print("Final value of the counter:", shared_counter.value)

توضیح کد بالا:

  • خط ۳: یک قفل می‌سازیم.
  • خط ۹: قبل از شروع کار با منبع اشتراکی قفل را می‌بندیم.
  • خط ۱۲: بعد از اتمام کار با منبع اشتراکی قفل را باز می‌کنیم.

البته می‌توان به جای استفاده از acquire و release از دستور with نیز استفاده کرد.

import multiprocessing

lock = multiprocessing.Lock()

# Shared resource
shared_counter = multiprocessing.Value('i', 0)

def increment_counter(shared_counter, lock):
    with lock:
        for _ in range(100000):
            shared_counter.value += 1

if __name__ == '__main__':
    # Create multiple processes
    processes = []
    for _ in range(5):
        p = multiprocessing.Process(target=increment_counter, args=(shared_counter, lock))
        p.start()
        processes.append(p)

    # Wait for all processes to finish
    for p in processes:
        p.join()

    # Print the final value of the shared counter
    print("Final value of the counter:", shared_counter.value)
Please login to bookmark Close
نظرات

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

فهرست مطالب

سرفصل دوره

تمرین

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

پاسخ تمرین ها

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

اشتراک گذاری

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

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

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

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

تنظیمات

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