كيفية إنشاء وتنفيذ عمليات التزامن باستخدام asyncio في Python

معالجة التزامن (Concurrency) تُعد من المواضيع الأساسية في البرمجة الحديثة، حيث تساعد على تنفيذ عدة مهام بشكل متزامن لتحسين الأداء. Python توفر مكتبة قوية تُعرف بـ asyncio التي تُستخدم لإنشاء برامج غير متزامنة تتعامل بكفاءة مع عمليات الإدخال/الإخراج والمهام الأخرى التي تستغرق وقتًا طويلاً. في هذا المقال، سنتعرف على كيفية إنشاء وتنفيذ عمليات التزامن باستخدام asyncio في Python.

ما هي مكتبة asyncio؟

asyncio هي مكتبة في Python تُستخدم لكتابة برامج غير متزامنة (Asynchronous) ومتعددة المهام (Concurrent). تُساعد asyncio في تنفيذ عدة مهام بالتوازي دون الحاجة إلى استخدام عدة خيوط (Threads) أو عمليات (Processes)، مما يجعلها مناسبة للتطبيقات التي تتطلب تنفيذ عمليات الإدخال/الإخراج المكثفة، مثل خوادم الويب أو برامج الشبكات.

كيفية تثبيت asyncio

مكتبة asyncio مضمنة بالفعل في Python ابتداءً من الإصدار 3.4، لذا لا تحتاج إلى تثبيتها. يمكنك البدء في استخدامها مباشرة في برامجك.

كتابة المهام غير المتزامنة باستخدام asyncio

أول خطوة في استخدام asyncio هي كتابة المهام غير المتزامنة. يتم تعريف هذه المهام باستخدام الكلمة المحجوزة async وawait. دعنا نبدأ بمثال بسيط:


import asyncio

async def say_hello():
    print("مرحبا!")
    await asyncio.sleep(1)
    print("وداعًا!")

async def main():
    await say_hello()

asyncio.run(main())

في هذا المثال، نقوم بتعريف دالة غير متزامنة say_hello باستخدام async def. داخل هذه الدالة، نستخدم await لتعليق التنفيذ لمدة ثانية واحدة باستخدام asyncio.sleep(). يتم تشغيل الدالة main التي تستدعي say_hello باستخدام asyncio.run().

تشغيل عدة مهام بشكل متزامن

أحد أهم فوائد asyncio هو القدرة على تشغيل عدة مهام بشكل متزامن. يمكن القيام بذلك باستخدام asyncio.gather() لجمع المهام وتشغيلها بالتوازي:


async def download_file(file_name):
    print(f"بدء تنزيل {file_name}...")
    await asyncio.sleep(2) # محاكاة عملية التنزيل
    print(f"اكتمل تنزيل {file_name}!")

async def main():
    files = ['file1.txt', 'file2.txt', 'file3.txt']
    await asyncio.gather(*(download_file(file) for file in files))

asyncio.run(main())

في هذا المثال، نقوم بتعريف دالة download_file التي تحاكي عملية تنزيل ملف باستخدام asyncio.sleep(). نقوم بتشغيل عدة مهام تنزيل بشكل متزامن باستخدام asyncio.gather() في الدالة main.

التعامل مع الوقت والتنظيم الزمني

asyncio توفر أدوات للتعامل مع الوقت، مثل تأجيل تنفيذ المهام أو تنفيذها بشكل دوري. يمكن استخدام asyncio.sleep() لتأخير المهام:


async def delayed_message(message, delay):
    await asyncio.sleep(delay)
    print(message)

async def main():
    await delayed_message("هذه الرسالة تظهر بعد 3 ثواني", 3)

asyncio.run(main())

في هذا المثال، نقوم بتعريف دالة delayed_message التي تعرض رسالة بعد تأخير محدد باستخدام asyncio.sleep(). نقوم بتشغيل هذه الدالة في main مع تأخير 3 ثواني.

التعامل مع الطوارئ والإلغاء

asyncio يسمح بإلغاء المهام إذا كانت تحتاج إلى التوقف قبل اكتمالها. يمكن استخدام asyncio.CancelledError للتعامل مع الإلغاء:


async def task():
    try:
        print("بدء المهمة...")
        await asyncio.sleep(5)
        print("اكتملت المهمة!")
    except asyncio.CancelledError:
        print("تم إلغاء المهمة!")

async def main():
    task_obj = asyncio.create_task(task())
    await asyncio.sleep(2) # انتظار لبعض الوقت قبل الإلغاء
    task_obj.cancel()
    await task_obj

asyncio.run(main())

في هذا المثال، نقوم بإنشاء مهمة task ونقوم بإلغائها بعد مرور ثانيتين باستخدام task_obj.cancel(). نتعامل مع استثناء CancelledError داخل المهمة لإدارة الإلغاء بشكل صحيح.

تنفيذ مهام متكررة باستخدام asyncio

يمكن استخدام asyncio.create_task() لإنشاء مهام تستمر في التنفيذ بشكل متكرر، مثل خدمة التي تستمع لطلبات المستخدمين:


async def repeated_task():
    while True:
        print("تنفيذ مهمة متكررة...")
        await asyncio.sleep(2)

async def main():
    task_obj = asyncio.create_task(repeated_task())
    await asyncio.sleep(10) # تشغيل المهمة المتكررة لمدة 10 ثواني
    task_obj.cancel()

asyncio.run(main())

في هذا المثال، نقوم بإنشاء مهمة متكررة تستمر في الطباعة كل ثانيتين، ثم نقوم بإلغاء المهمة بعد مرور 10 ثواني.

مقارنة asyncio مع مكتبات التزامن الأخرى

asyncio تُعد واحدة من أدوات التزامن المتاحة في Python. ومع ذلك، هناك أدوات أخرى مثل threading و multiprocessing لكل منها استخداماتها الخاصة:

  • asyncio: مثالية للمهام غير المتزامنة مثل عمليات الإدخال/الإخراج المكثفة. تُستخدم لإنشاء تطبيقات شبكة وخوادم الويب بكفاءة.
  • threading: تُستخدم للتزامن مع المهام التي تتطلب تنفيذًا متوازيًا عبر خيوط متعددة. مناسبة للمهام التي تستفيد من تنفيذ متعدد الخيوط.
  • multiprocessing: تُستخدم لإنشاء عمليات متعددة تعمل بالتوازي، وهي مناسبة للمهام التي تستفيد من تعدد المعالجات.

الخلاصة

تُعد مكتبة asyncio أداة قوية لكتابة برامج غير متزامنة في Python. باستخدام asyncio، يمكنك تنفيذ عدة مهام بالتوازي، التعامل مع عمليات الإدخال/الإخراج بكفاءة، وإدارة المهام المتزامنة بشكل مرن. سواء كنت تطور خوادم الويب أو أدوات الشبكة أو التطبيقات الأخرى التي تتطلب تزامنًا عاليًا، فإن asyncio توفر لك الأدوات اللازمة لتحقيق هذا الهدف بكفاءة وسهولة.