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

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

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

ابدأ الدورة

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



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



1. الأساسيات: std::thread و std::async



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



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

int long_running_task(int input) { std::this_thread::sleep_for(std::chrono::seconds(2)); return input * 10;}

int main() { std::cout << "نقوم بتشغيل مهمة غير متزامنة..."; std::future<int> result = std::async(std::launch::async, long_running_task, 5); // نقوم بشيء مفيد أثناء تنفيذ المهمة std::cout << "الخيط الرئيسي يواصل العمل..."; // الحصول على النتيجة (يتم الحظر إذا لم تكتمل المهمة بعد) int value = result.get(); std::cout << "النتيجة: " << value << std::endl; return 0;}


النقاط الرئيسية:

  • std::launch::async — يضمن التشغيل في خيط منفصل.
  • std::launch::deferred — يؤجل التنفيذ حتى استدعاء get().
  • طريقة get() تحظر الخيط حتى الحصول على النتيجة.


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



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



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

void worker(std::promise<int> prom) { try { int result = 42; // حسابات معقدة prom.set_value(result); } catch (...) { prom.set_exception(std::current_exception()); }}

int main() { std::promise<int> prom; std::future<int> fut = prom.get_future(); std::thread t(worker, std::move(prom)); // الحصول على النتيجة int value = fut.get(); std::cout << "تم استلام القيمة: " << value << std::endl; t.join(); return 0;}


الميزات الهامة:

  • لا يمكن نسخ promise، بل نقله فقط.
  • يتم نقل الاستثناءات عبر set_exception.
  • يمكن استخدام future مرة واحدة فقط (استلام لمرة واحدة).


3. Coroutines في C++20: النهج الحديث



تعتبر coroutines أداة قوية تمت إضافتها في C++20. تسمح بإيقاف واستئناف تنفيذ الدالة دون حظر الخيط. هذا مثالي لعمليات الإدخال/الإخراج غير المتزامنة والمولدات.



#include <iostream>#include <coroutine>#include <future>

struct SimpleTask { struct promise_type { SimpleTask get_return_object() { return {}; } std::suspend_never initial_suspend() { return {}; } std::suspend_never final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception() { std::exit(1); } };};

SimpleTask async_operation() { std::cout << "بداية coroutine";

المدونات

توصيات الكتب