🔥 أحدث الأخبار

موقع يهتم بكل ماهو جديد في عالم التكنولوجيا والرياضة

كورس C++ المتقدم – الحلقة الخامسة: Multithreading (التنفيذ المتعدد)


 

كورس 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++ 🚀

تعليقات

💬 🙋🏻‍♂️