كورس C++ المتقدم – الحلقة الخامسة: Multithreading (التنفيذ المتعدد)
#برمجة
مقدمة
مرحباً بك في الحلقة الخامسة من المستوى المتقدم في C++.
في الحلقات السابقة تعلمنا:
- Templates
- Exception Handling
- Smart Pointers
- Lambda Functions
واليوم سندخل واحد من أقوى مواضيع البرمجة الحديثة:
Multithreading
أي التنفيذ المتعدد داخل نفس البرنامج.
ما معنى Thread؟
الـ Thread هو:
مسار تنفيذ داخل البرنامج
يمكن للبرنامج أن يحتوي على أكثر من Thread يعملون في نفس الوقت.
مثال بسيط من الحياة
تخيل أنك:
- تشاهد فيديو
- وتحمّل ملف
- وتكتب رسالة
كلها تحدث في نفس الوقت.
هذا هو مفهوم Multithreading.
لماذا نحتاج Multithreading؟
✔ تسريع البرامج
✔ تنفيذ عدة مهام معاً
✔ تحسين الأداء
✔ استغلال المعالج (CPU) بشكل أفضل
المكتبة المطلوبة
#include <thread>
أول Thread بسيط
#include <iostream>
#include <thread>
using namespace std;
void hello()
{
cout << "Hello from thread" << endl;
}
int main()
{
thread t1(hello);
t1.join();
cout << "Main finished";
return 0;
}
الناتج
Hello from thread
Main finished
شرح الكود
thread t1(hello);
يعني:
تشغيل الدالة hello في Thread منفصل
ما معنى join؟
t1.join();
يعني:
انتظر انتهاء الـ Thread قبل إكمال البرنامج
تشغيل أكثر من Thread
#include <iostream>
#include <thread>
using namespace std;
void task1()
{
cout << "Task 1 running" << endl;
}
void task2()
{
cout << "Task 2 running" << endl;
}
int main()
{
thread t1(task1);
thread t2(task2);
t1.join();
t2.join();
cout << "All done";
return 0;
}
ملاحظة مهمة
الترتيب قد يتغير لأن التنفيذ متوازي:
Task 2 running
Task 1 running
All done
أو العكس.
استخدام Lambda مع Thread
#include <iostream>
#include <thread>
using namespace std;
int main()
{
thread t1([]()
{
cout << "Thread using lambda" << endl;
});
t1.join();
return 0;
}
تمرير بيانات إلى Thread
#include <iostream>
#include <thread>
using namespace std;
void printNumber(int x)
{
cout << "Number: " << x << endl;
}
int main()
{
thread t1(printNumber, 10);
t1.join();
return 0;
}
تمرير أكثر من قيمة
#include <iostream>
#include <thread>
using namespace std;
void add(int a, int b)
{
cout << a + b << endl;
}
int main()
{
thread t1(add, 5, 7);
t1.join();
return 0;
}
join vs detach
join
ينتظر انتهاء الـ Thread
detach
يشغله في الخلفية
t1.detach();
مثال detach
#include <iostream>
#include <thread>
using namespace std;
void run()
{
cout << "Running in background" << endl;
}
int main()
{
thread t1(run);
t1.detach();
cout << "Main continues";
return 0;
}
الفرق
| join | detach |
|---|---|
| ينتظر | لا ينتظر |
| آمن | يحتاج حذر |
| مستخدم كثيراً | أقل استخدام |
مشكلة خطيرة: Race Condition
عندما يستخدم Threadان نفس المتغير.
مثال
#include <iostream>
#include <thread>
using namespace std;
int counter = 0;
void increment()
{
for(int i = 0; i < 1000; i++)
counter++;
}
int main()
{
thread t1(increment);
thread t2(increment);
t1.join();
t2.join();
cout << counter;
return 0;
}
النتيجة المتوقعة
2000
لكن قد لا تكون كذلك بسبب التداخل.
الحل: Mutex
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex mtx;
int counter = 0;
void increment()
{
for(int i = 0; i < 1000; i++)
{
mtx.lock();
counter++;
mtx.unlock();
}
}
int main()
{
thread t1(increment);
thread t2(increment);
t1.join();
t2.join();
cout << counter;
return 0;
}
ما هو Mutex؟
هو:
قفل يمنع أكثر من Thread من الدخول لنفس الكود في نفس الوقت
lock_guard (طريقة أفضل)
lock_guard<mutex> lock(mtx);
مثال
void increment()
{
for(int i = 0; i < 1000; i++)
{
lock_guard<mutex> lock(mtx);
counter++;
}
}
لماذا lock_guard أفضل؟
✔ يغلق تلقائياً
✔ يمنع النسيان
✔ أكثر أماناً
مثال عملي: تحميل ملفات
#include <iostream>
#include <thread>
using namespace std;
void download1()
{
cout << "Downloading file 1..." << endl;
}
void download2()
{
cout << "Downloading file 2..." << endl;
}
int main()
{
thread t1(download1);
thread t2(download2);
t1.join();
t2.join();
cout << "Downloads finished";
return 0;
}
استخدامات Multithreading
✔ الألعاب
✔ المتصفحات
✔ التطبيقات الكبيرة
✔ السيرفرات
✔ تحميل الملفات
✔ الذكاء الاصطناعي
أخطاء شائعة
❌ نسيان join()
❌ استخدام المتغيرات بدون mutex
❌ استخدام detach بدون إدارة
❌ Race Conditions
تمرين 1
أنشئ Thread يطبع "Hello".
تمرين 2
أنشئ Threadين لطباعة أرقام مختلفة.
تمرين 3
اصنع عداد باستخدام Thread.
تمرين 4
استخدم mutex لحماية المتغير.
تمرين 5
اصنع برنامج تحميل وهمي باستخدام Thread.
ملخص الحلقة الخامسة
تعلمنا:
- Thread
- join
- detach
- Lambda مع Thread
- Passing arguments
- Race Condition
- Mutex
- lock_guard
- تنفيذ متعدد المهام
في الحلقة السادسة سنتعلم:
🔥 File Handling Advanced + Serialization
وسنتعلم:
- حفظ البيانات ككائنات
- قراءة وكتابة ملفات احترافية
- تحويل البيانات إلى صيغة قابلة للتخزين
- بناء نظام قاعدة بيانات بسيط داخل C++ 🚀

تعليقات
إرسال تعليق