1. المقدمة
Python هي لغة برمجة متعددة الاستخدامات توفر أدوات قوية خاصة في مجالات معالجة البيانات، التعلم الآلي، وتطوير الويب. من بين هذه الأدوات، يُعتبر وحدة multiprocessing مكتبة أساسية لتحقيق المعالجة المتوازية. في هذا المقال، سنشرح بالتفصيل كيفية استخدام وحدة multiprocessing من الأساسيات وحتى التطبيقات المتقدمة، مع شروح مرئية وتقنيات عملية لاستخراج أقصى أداء.
2. ما هي multiprocessing؟
2.1 الحاجة إلى المعالجة المتوازية
بشكل افتراضي يعمل Python بخيط واحد (Single-thread)، ولكن عند التعامل مع عمليات ثقيلة أو بيانات ضخمة، فإن هذا الأسلوب يواجه حدودًا في السرعة. باستخدام المعالجة المتوازية يمكن تنفيذ مهام متعددة في وقت واحد والاستفادة من جميع أنوية وحدة المعالجة المركزية لتقليل وقت التنفيذ. تُتيح multiprocessing تجاوز قفل المترجم العام (GIL) في Python عبر استخدام عمليات متعددة لتنفيذ معالجة متوازية حقيقية.
2.2 الفرق عن الخيط الواحد
في المعالجة بخيط واحد يتم تنفيذ المهام بشكل تسلسلي ضمن عملية واحدة، بينما في المعالجة المتعددة يمكن تنفيذ المهام بشكل متزامن عبر عمليات متعددة. هذا يحسن الأداء بشكل خاص في المهام المرتبطة بالـ CPU مثل الحسابات العددية واسعة النطاق أو تحليل البيانات.
3. البنية الأساسية لوحدة multiprocessing
3.1 استخدام الفئة Process
الأساس في وحدة multiprocessing
هو استخدام الفئة Process. باستخدامها يمكن إنشاء عمليات جديدة بسهولة وتنفيذ المعالجة المتوازية.
import multiprocessing
def worker_function():
print("تم تنفيذ عملية جديدة")
if __name__ == "__main__":
process = multiprocessing.Process(target=worker_function)
process.start()
process.join()
في هذا المثال، يتم تنفيذ worker_function
في عملية جديدة. باستخدام start()
يتم بدء العملية، وباستخدام join()
ننتظر حتى تنتهي العملية.
3.2 تمرير الوسائط إلى العملية
لتمرير الوسائط إلى العملية نستخدم معامل args
كما في المثال التالي:
def worker(number):
print(f'تم تنفيذ العامل {number}')
if __name__ == "__main__":
process = multiprocessing.Process(target=worker, args=(5,))
process.start()
process.join()
هكذا يمكن تمرير بيانات ديناميكية إلى العملية لتنفيذ المعالجة بشكل متزامن.
4. مشاركة البيانات والمزامنة
4.1 مشاركة البيانات باستخدام الذاكرة المشتركة
في المعالجة المتعددة يمكن مشاركة البيانات بشكل آمن عبر Value وArray. هذه الكائنات توفر ذاكرة مشتركة يمكن الوصول إليها من عدة عمليات بأمان.
import multiprocessing
def increment_value(shared_value):
with shared_value.get_lock():
shared_value.value += 1
if __name__ == "__main__":
shared_value = multiprocessing.Value('i', 0)
processes = [multiprocessing.Process(target=increment_value, args=(shared_value,)) for _ in range(5)]
for process in processes:
process.start()
for process in processes:
process.join()
print(f'القيمة النهائية: {shared_value.value}')
في هذا المثال، 5 عمليات تقوم بزيادة القيمة المشتركة في وقت واحد مع منع التعارض باستخدام get_lock()
.
4.2 منع تعارض البيانات باستخدام القفل
عند قيام عمليات متعددة بتعديل البيانات في نفس الوقت، نستخدم آلية القفل (Lock) لضمان المزامنة.

5. توزيع المهام باستخدام مجموعة العمليات
5.1 استخدام الفئة Pool
يمكن باستخدام Pool
تقسيم المهام وتنفيذها على عدة عمليات بالتوازي.
from multiprocessing import Pool
def square(x):
return x * x
if __name__ == "__main__":
with Pool(4) as pool:
results = pool.map(square, range(10))
print(results)
في هذا المثال يتم حساب مربع عناصر القائمة عبر 4 عمليات بشكل متوازي.
رسم توضيحي: توزيع المهام باستخدام Pool

5.2 مثال متقدم: استخدام starmap مع وسائط متعددة
def multiply(x, y):
return x * y
if __name__ == "__main__":
with Pool(4) as pool:
results = pool.starmap(multiply, [(1, 2), (3, 4), (5, 6), (7, 8)])
print(results)
6. الاستفادة المثلى من موارد CPU
6.1 تحسين عدد العمليات باستخدام cpu_count()
يمكن استخدام multiprocessing.cpu_count()
للحصول على عدد أنوية المعالج وضبط عدد العمليات وفقًا لذلك.
from multiprocessing import Pool, cpu_count
if __name__ == "__main__":
with Pool(cpu_count() - 1) as pool:
results = pool.map(square, range(100))
print(results)
6.2 الاستخدام الفعّال لموارد النظام
من الأفضل ترك نواة واحدة على الأقل للنظام لتجنب التأثير على المهام الأخرى.
7. حالات الاستخدام وأفضل الممارسات
7.1 أمثلة على حالات الاستخدام
يمكن استخدام multiprocessing في الحالات التالية:
- معالجة البيانات الضخمة: مثل قراءة ومعالجة عدة ملفات في نفس الوقت.
- التدريب المتوازي في التعلم الآلي: لتسريع تدريب النماذج.
- جمع بيانات الويب: لاستخراج البيانات بكفاءة من عدة صفحات في وقت واحد.
7.2 أفضل الممارسات
- توزيع الموارد بشكل مثالي: ضبط عدد العمليات حسب عدد الأنوية المتاحة.
- استخدام التصحيح والتسجيل: عبر
logging
لمتابعة حالة كل عملية.
import logging
import multiprocessing
def worker_function():
logging.info(f'تم بدء العملية {multiprocessing.current_process().name}')
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
process = multiprocessing.Process(target=worker_function, name='عامل1')
process.start()
process.join()
- تنفيذ معالجة الأخطاء: عبر استخدام try-except لمنع تأثير خطأ عملية واحدة على بقية العمليات.
8. الخاتمة
في هذا المقال شرحنا كيفية استخدام وحدة multiprocessing في Python لتحقيق المعالجة المتوازية بكفاءة. من استخدام الفئة Process إلى مشاركة البيانات وتوزيع المهام باستخدام Pool وحتى أفضل الممارسات.
باستخدام multiprocessing بشكل صحيح يمكن تحسين الأداء بشكل ملحوظ في مشاريع مثل معالجة البيانات الكبيرة، تدريب نماذج التعلم الآلي، أو جمع البيانات من الويب. إنها أداة قوية لتعزيز قدرات Python في الاستفادة من موارد النظام.