ما هي البرمجة غير المتزامنة في بايثون
البرمجة غير المتزامنة هي أسلوب لكتابة الكود يتم فيه تنفيذ المهام ليس بشكل تسلسلي، بل بشكل متوازٍ أو مع انتظار الأحداث دون حظر التدفق الرئيسي للتنفيذ. في البرمجة الحديثة، يلعب الاستخدام الفعال للموارد ووقت تنفيذ التطبيقات دورًا محوريًا.
تتيح البرمجة غير المتزامنة ما يلي:
- تسريع تنفيذ المهام
- تحسين استجابة البرامج
- الاستخدام الأمثل لموارد النظام
المزايا الرئيسية للبرمجة غير المتزامنة
مجالات الاستخدام
البرمجة غير المتزامنة مفيدة بشكل خاص لعمليات الإدخال والإخراج:
- التعامل مع الملفات
- طلبات الشبكة (HTTP API)
- التفاعل مع قواعد البيانات
- معالجة WebSockets
- استخراج كميات كبيرة من البيانات
الفرق عن تعدد الخيوط
على عكس تعدد الخيوط، لا تتطلب البرمجة غير المتزامنة إنشاء خيوط أو عمليات إضافية. هذا يقلل الحمل على النظام ويتجنب مشاكل الحظر ومزامنة البيانات بين الخيوط.
كيف تعمل البرمجة غير المتزامنة في بايثون
توفر بايثون دعمًا مدمجًا للبرمجة غير المتزامنة من خلال وحدة asyncio، التي تمت إضافتها رسميًا إلى المكتبة القياسية بدءًا من الإصدار 3.4.
المفاهيم الأساسية
async def— تعريف دالة غير متزامنة (كوروتين)await— يشير إلى ضرورة انتظار تنفيذ الكوروتينasyncio— الوحدة القياسية للتعامل مع المهام غير المتزامنةevent loop— حلقة معالجة الأحداث التي تدير تنفيذ الكوروتينات
مثال أساسي لدالة غير متزامنة
import asyncio
async def greet():
print("مرحبًا!")
await asyncio.sleep(1)
print("مرت ثانية واحدة")
asyncio.run(greet())
في هذا المثال، await asyncio.sleep(1) يحاكي انتظار عملية مكثفة للموارد، مثل طلب شبكة.
إنشاء واستخدام الدوال غير المتزامنة
تعريف دالة غير متزامنة
لإنشاء دالة غير متزامنة، استخدم الكلمة المفتاحية async قبل تعريف الدالة:
async def fetch_data():
print("جاري طلب البيانات...")
await asyncio.sleep(2)
print("تم استلام البيانات")
استدعاء دالة غير متزامنة
يتم استدعاء الدالة غير المتزامنة من خلال asyncio.run():
asyncio.run(fetch_data())
التنفيذ المتوازي لعدة مهام
استخدام asyncio.gather()
لتشغيل عدة كوروتينات بشكل متوازٍ، استخدم asyncio.gather():
async def task(name, delay):
print(f"بدء المهمة {name}")
await asyncio.sleep(delay)
print(f"المهمة {name} اكتملت")
async def main():
await asyncio.gather(
task("أ", 2),
task("ب", 1),
task("ج", 3)
)
asyncio.run(main())
طرق بديلة لتشغيل المهام
بالإضافة إلى asyncio.gather()، يمكنك استخدام:
asyncio.create_task()— لإنشاء مهام منفصلةasyncio.wait()— لانتظار اكتمال المهام مع إعدادات إضافيةasyncio.as_completed()— للحصول على النتائج فور جاهزيتها
المكررات والمولدات غير المتزامنة
إنشاء مكرر غير متزامن
لمعالجة تدفقات البيانات بشكل غير متزامن، استخدم المكررات غير المتزامنة:
class AsyncCounter:
def __init__(self, max_count):
self.max_count = max_count
s