توفر وحدة multiprocessing في Python أدوات قوية لإنشاء برامج متوازية تستفيد بكفاءة من معالجات متعددة النواة. على عكس تعدد الخيوط التقليدي المقيد بـ Global Interpreter Lock (GIL)، تتيح multiprocessing تشغيل عدة عمليات في وقت واحد، لكل منها ذاكرة خاصة وتنفيذ مستقل.
المبادئ الأساسية لعمل multiprocessing
تعتمد المعالجة المتعددة في Python على إنشاء عمليات منفصلة يمكن تنفيذها بالتوازي على أنوية معالج مختلفة. تعمل كل عملية في مساحة ذاكرة معزولة، مما يلغي مشاكل البيانات المشتركة الشائعة في تعدد الخيوط.
المكونات الرئيسية لوحدة multiprocessing تشمل:
- Process — فئة لإنشاء وإدارة العمليات المنفردة
- Pool — مجموعة عمليات لتنفيذ مهام متعددة بكفاءة
- Queue — طوابير لنقل البيانات بأمان بين العمليات
- Lock — آليات تزامن للتحكم في الوصول إلى الموارد
- Manager — كائنات لإدارة البيانات المشتركة
متى تستخدم multiprocessing
تكون multiprocessing أكثر فعالية في الحالات التالية:
المهام المكثفة على المعالج (CPU-intensive): الحسابات الرياضية، معالجة الصور، تحليل البيانات، الحسابات العلمية. تستفيد هذه المهام من التنفيذ المتوازي على أنوية معالج مختلفة.
معالجة كميات كبيرة من البيانات: عندما تحتاج لتطبيق نفس الدالة على عناصر متعددة، يمكن لـ multiprocessing تسريع التنفيذ بشكل كبير.
المهام المستقلة: العمليات التي لا تتطلب تبادل بيانات متكرر بين العمليات.
للمهام المكثفة على الإدخال/الإخراج (I/O-intensive) مثل العمل مع الملفات أو طلبات الشبكة، يُفضل استخدام البرمجة غير المتزامنة (asyncio) أو تعدد الخيوط.
إنشاء وإدارة العمليات
مثال أساسي باستخدام فئة Process
import multiprocessing
import time
def worker_task(name, duration):
"""دالة يتم تنفيذها في عملية منفصلة"""
print(f"العملية {name} بدأت العمل")
time.sleep(duration)
print(f"العملية {name} أنهت العمل")
if __name__ == "__main__":
# إنشاء العمليات
process1 = multiprocessing.Process(target=worker_task, args=("Worker-1", 3))
process2 = multiprocessing.Process(target=worker_task, args=("Worker-2", 2))
# تشغيل العمليات
start_time = time.time()
process1.start()
process2.start()
# انتظار انتهاء العمليات
process1.join()
process2.join()
end_time = time.time()
print(f"إجمالي وقت التنفيذ: {end_time - start_time:.2f} ثانية")
وراثة فئة Process
import multiprocessing
import os
class CustomProcess(multiprocessing.Process):
def __init__(self, name, work_count):
super().__init__()
self.name = name
self.work_count = work_count
def run(self):
"""الطريقة التي يتم تنفيذها في العملية"""
print(f"العملية {self.name} (PID: {os.getpid()}) بدأت العمل")
for i in range(self.work_count):
print(f"{self.name}: تنفيذ المهمة {i+1}")
time.sleep(1)
print(f"العملية {self.name} أنهت العمل")
if __name__ == "__main__":
processes = []
# إنشاء عدة عمليات
for i in range(3):
p = CustomProcess(f"Process-{i+1}", 3)
processes.append(p)
p.start()
# انتظار انتهاء جميع العمليات
for p in processes:
p.join()
العمل مع مجموعة العمليات (Pool)
توفر Pool واجهة سهلة لإدارة