في سياق برمجي متعدد الخيوط، تصبح التواصل بين الخيوط أمرًا ضروريًا لضمان تناغم تنفيذ البرنامج. في الكود الذي قدمته، تحتاج إلى تحقيق تبادل المعلومات بين الخيطين console_task
و dialer_task
دون الاعتماد على المتغيرات العامة.
لتحقيق هذا، يمكنك استخدام مفهوم الـ”Inter-Thread Communication” (التواصل بين الخيوط). يمكن استخدام العديد من الطرق لتحقيق ذلك، ولكن يمكن استخدام الـ”std::condition_variable” كأداة فعالة.
أولاً، قم بإضافة المكتبة اللازمة:
cpp#include
#include
ثم، قم بتعريف متغير i
ومتغير mutex
و condition_variable
كمتغيرات عامة في نطاق البرنامج الرئيسي:
cppint i = 0;
std::mutex mtx;
std::condition_variable cv;
الآن، قم بتعديل الكود ليصبح كالتالي:
cpp#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "console.hpp"
using namespace std;
int i = 0;
std::mutex mtx;
std::condition_variable cv;
void console_task() {
// انتظر حتى يتم تحديث i في dialer_task
std::unique_lock lock(mtx) ;
cv.wait(lock);
// استخدم قيمة i
console(i);
}
void dialer_task() {
while (1) {
// تحديث قيمة i
{
std::lock_guard lock(mtx) ;
printf("LOOP %d\n", i);
i++;
}
// إشعار console_task بتحديث قيمة i
cv.notify_one();
sleep(5);
}
}
int main() {
thread t1(console_task);
thread t2(dialer_task);
t1.join();
t2.join();
return 0;
}
في هذا الكود، تم استخدام std::condition_variable
لإشعار console_task
عندما يتم تحديث قيمة i
في dialer_task
. تم استخدام std::unique_lock
للانتظار حتى يتم تحديث i
في dialer_task
وتأمين std::lock_guard
لتحديث i
بشكل آمن.
المزيد من المعلومات
التواصل بين الخيوط في برمجة C++ يعد جزءًا أساسيًا من تصميم التطبيقات متعددة الخيوط، حيث يسمح بالتحكم الفعّال في تنفيذ البرنامج وتبادل المعلومات بين الخيوط بطريقة آمنة. في الكود الذي قدمته، قمت بتطبيق نمط Producer-Consumer حيث يقوم dialer_task
بإنتاج قيم للمتغير i
و console_task
يعتبر المستهلك.
لنقم بتوضيح بعض الجوانب المهمة:
-
std::mutex
(القفل):- تم استخدام
std::mutex
لتأمين الوصول إلى المتغيرi
من قبل الخيطين. هذا يضمن أنه لا يتم الوصول إليه في نفس الوقت من قبل الخيوط المختلفة.
- تم استخدام
-
std::condition_variable
(المتغير الشرطي):- يتيح
std::condition_variable
للخيوط الانتظار والإشعار بتغيير في الحالة. في هذا السياق، تستخدم لتحقيق تبادل آمن للمعلومات بينdialer_task
وconsole_task
.
- يتيح
-
std::unique_lock
وstd::lock_guard
:std::unique_lock
تستخدم للتحكم في دورة الحياة للنفس بمرونة، وهي مفيدة في سيناريوهات تواصل معقدة. في هذا السياق، تستخدم لانتظار التغيير في المتغيرi
.std::lock_guard
تستخدم لتأمين القفل (std::mutex
) بشكل تلقائي عند إنشاء الكائن. هنا، تستخدم لتأمينi
أثناء تحديثه.
-
إشعار الـ
std::condition_variable
:- يتم استخدام
cv.notify_one()
فيdialer_task
لإشعار أي خيط ينتظر (std::unique_lock
) علىcv
أن يستمر في التنفيذ بعد تحديث المتغيرi
.
- يتم استخدام
-
تحكم بدورة التنفيذ:
- يتم تحكم بدورة التنفيذ باستخدام
std::unique_lock
وcv.wait()
فيconsole_task
، حيث يتم إيقاف تنفيذه حتى يتم تحديث المتغيرi
فيdialer_task
.
- يتم تحكم بدورة التنفيذ باستخدام
هذه الأدوات تعتبر ضرورية لضمان تناغم تنفيذ البرنامج متعدد الخيوط وتجنب مشاكل التنازع. تحسين الأداء وضمان الاستقرار يتطلب تصميم دقيق لتبادل المعلومات والتحكم في التنفيذ بطريقة فعّالة وآمنة.