البرمجة غير المتزامنة في C++: دليل شامل عملي

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

البرمجة غير المتزامنة في C++: دليل شامل عملي

البرمجة غير المتزامنة في C++ هي نهج يسمح بتنفيذ مهام متعددة بشكل متوازٍ دون حظر سير التنفيذ الرئيسي. على عكس الكود المتزامن حيث تنتظر كل عملية اكتمال العملية السابقة، يمكن للكود غير المتزامن بدء عمليات طويلة (إدخال/إخراج، طلبات شبكة، حسابات) ومواصلة تنفيذ مهام أخرى أثناء اكتمال هذه العمليات في الخلفية. هذا أمر بالغ الأهمية لبناء تطبيقات سريعة الاستجابة، خاصة في صناعة الألعاب، خوادم الويب، وأنظمة الوقت الفعلي.

في هذه المقالة، سنشرح البرمجة غير المتزامنة في C++ عملياً: من الآليات الكلاسيكية std::async و std::future إلى coroutines الحديثة في C++20. ستتعلم كيفية استخدام هذه الأدوات بشكل صحيح، وتجنب الأخطاء الشائعة، وبناء أنظمة غير متزامنة فعالة.



1. أساسيات عدم التزامن: std::async و std::future

توفر المكتبة القياسية لـ C++11 طريقة بسيطة لتشغيل المهام غير المتزامنة - الدالة std::async والكلاس std::future. تقوم std::async بتشغيل دالة في خيط منفصل (أو مجموعة خيوط) وتعيد std::future الذي يحتوي على نتيجة التنفيذ.



مثال 1: تشغيل مهمة غير متزامنة أساسية

#include <iostream>#include <future>#include <thread>#include <chrono>

int longComputation(int n) { std::this_thread::sleep_for(std::chrono::seconds(2)); return n * n;}

int main() { std::cout << "جارٍ تشغيل المهمة غير المتزامنة..." << std::endl; std::future<int> result = std::async(std::launch::async, longComputation, 10);

// بينما يتم تنفيذ المهمة، يمكن القيام بعمل آخر std::cout << "الخيط الرئيسي يواصل العمل..." << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1));

// الحصول على النتيجة (يحظر الخيط إذا لم تكتمل المهمة بعد) int value = result.get(); std::cout << "النتيجة: " << value << std::endl; return 0;}


نقاط مهمة:

  • std::launch::async يضمن التشغيل في خيط منفصل.
  • result.get() يحظر الخيط الحالي حتى الحصول على النتيجة.
  • إذا لم يتم استدعاء get()، فقد يقوم مدمر std::future بحظر التنفيذ حتى اكتمال المهمة.


مثال 2: معالجة الاستثناءات في المهام غير المتزامنة

#include <iostream>#include <future>#include <stdexcept>

int riskyFunction(int x) { if (x < 0) throw std::runtime_error("رقم سالب!"); return x * 2;}

int main() { std::future<int> future = std::async(std::launch::async, riskyFunction, -5); try { int result = future.get(); std::cout << "النتيجة: " << result << std::endl; } catch (const std::exception& e) { std::cout << "استثناء: " << e.what() << std::endl; } return 0;}


2. العمل المتقدم مع std::future و std::promise

std::promise هي أداة للتحكم اليدوي في النتائج غير المتزامنة. يمكنك تعيين قيمة أو استثناء في خيط واحد، والحصول عليها عبر std::future في خيط آخر. هذا مفيد لتنفيذ أنماط غير متزامنة مخصصة، مثل نقل البيانات بين الخيوط.



مثال 3: استخدام std::promise لنقل البيانات

#include <iostream>#include <future>#include <thread>

void producer(std::promise<std::string> prom) { std::this_thread::sleep_for(std::chrono::seconds(1)); prom.set_value("البيانات جاهزة!");}

int main() { std::promise<std::string> promise; std::future<s

المدونات

توصيات الكتب