متغيرات الشرط وأنماط العاملين
نسّق بين الخيوط باستخدام std::condition_variable ونمط تجمع العاملين التقليدي.
متغيرات الشرط وأنماط العاملين درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.
ما متغير الشرط؟
يتيح متغير الشرط لخيط الانتظار حتى يشير خيط آخر إلى تغيّر شرط ما. ويُستخدم لتنسيق العمل بين المنتجين والمستهلكين.
أساسيات std::condition_variable
يعمل متغير الشرط مع std::mutex ودالة شرطية. يحرر الخيط المنتظر القفل أثناء الانتظار، ثم يستعيده عند الاستيقاظ.
#include <condition_variable>
#include <mutex>
#include <queue>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> tasks;
bool done = false;الانتظار على شرط
استخدم cv.wait(lock, predicate). فهو يفتح القفل ذريًا ويوقف الخيط مؤقتًا حتى وصول إشعار. وعند الاستيقاظ، يعيد قفل mutex ويتحقق من الشرط؛ فإذا كان خاطئًا، ينام مجددًا.
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !tasks.empty() || done; });الإشعار
يستدعي خيط المنتج cv.notify_one() أو cv.notify_all() بعد تغيير الحالة. يجب الاحتفاظ بالقفل أثناء تغيير الحالة.
{
std::lock_guard<std::mutex> lock(mtx);
tasks.push(42);
}
cv.notify_one();نمط المنتج-المستهلك
مثال تقليدي: يدفع المنتجون المهام، وينتظر المستهلكون وصول المهام.
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !tasks.empty() || done; });
if (done && tasks.empty()) break;
int task = tasks.front();
tasks.pop();
lock.unlock();
process(task);
}
}الاستيقاظات الزائفة
يمكن لخيط ينتظر على متغير شرط أن يستيقظ من دون إشعار. لذلك تستقبل wait دالة تحقّق — إذ تعيد التحقق عند كل استيقاظ.
notify_one مقارنةً بـ notify_all
استخدم notify_one عندما يستطيع منتظر واحد إحراز تقدم. واستخدم notify_all عندما تؤثر تغييرات الحالة في جميع المنتظرين، مثل إشارة إيقاف التشغيل.
الانتظارات المحددة بمهلة
تستيقظ wait_for(lock, duration) وwait_until(lock, time_point) إما عند وصول إشعار أو بعد انتهاء المهلة.
if (cv.wait_for(lock, 1s, [] { return ready; })) {
/* condition met */
} else {
/* timed out */
}الهيكل الأساسي لمجمّع خيوط التنفيذ
نمط شائع: تسحب مجموعة ثابتة من خيوط التنفيذ المهام من قائمة انتظار مشتركة. يُبنى ذلك باستخدام mutex وcondition_variable وqueue وراية إيقاف ذرّية.
تجنّب فقدان الإشعارات
عدّل الحالة المشتركة واستدعِ notify_* دائمًا مع الاحتفاظ بـ mutex أثناء تغيير الحالة، ويجوز تحريره قبل الإشعار مباشرةً، ما دام ترتيب العمليات مضمونًا. وإلا فقد يفوّت أحد المنتظرين الإشعار.
std::counting_semaphore (C++20)
للإشارات البسيطة القائمة على العدّ، أضاف C++20 النوع std::counting_semaphore، وهو أبسط من متغيرات الشرط في بعض الأنماط.
احذر من الجمود
قد يؤدي الاحتفاظ بعدة أقفال أثناء الانتظار على متغير شرط إلى حدوث جمود. احصل على الأقفال بترتيب متسق، واستخدم std::scoped_lock مع كائنات mutex المتعددة.
تحقق سريع
لماذا تستقبل cv.wait(lock, predicate) دالة تحقّق حتى عندما تريد فقط الانتظار لوصول إشعار؟
مراجعة
ينسّق متغير الشرط بين الخيوط التي تنتظر تغييرًا في الحالة. استخدم wait(lock, predicate) للتعامل مع الاستيقاظات الزائفة، وعدّل الحالة تحت حماية mutex، ثم استدعِ notify_one أو notify_all.
الأسئلة الشائعة
هل درس «متغيرات الشرط وأنماط العاملين» مجاني؟
نعم — نص درس «متغيرات الشرط وأنماط العاملين» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.
ماذا ستتعلم في «متغيرات الشرط وأنماط العاملين»؟
نسّق بين الخيوط باستخدام std::condition_variable ونمط تجمع العاملين التقليدي. تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟
لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «متغيرات الشرط وأنماط العاملين»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟
نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الانضمام إلى std::thread وفصلها
- std::mutex وlock_guard وunique_lock
- متغيرات الشرط وأنماط العاملين
- أساسيات std::async وstd::future