در حال بارگذاری...

چندنخی

چندنخی در سی‌پلاس‌پلاس به معنای اجرای همزمان چند مسیر اجرایی (Thread) در یک برنامه است. این تکنیک به توسعه‌دهندگان امکان می‌دهد تا وظایف همزمان را به شکل مؤثر پردازش کنند و از تمام توان پردازنده‌های چند هسته‌ای بهره‌برداری نمایند. استفاده از چندنخی در برنامه‌های سرور، پردازش داده‌های بزرگ، شبیه‌سازی‌های علمی و نرم‌افزارهای گرافیکی اهمیت ویژه‌ای دارد، زیرا باعث افزایش کارایی و کاهش زمان اجرای برنامه می‌شود.
در سی‌پلاس‌پلاس، استاندارد C++11 و نسخه‌های بعدی امکاناتی مانند std::thread، std::mutex، std::lock_guard و std::atomic را برای ایجاد، مدیریت و همگام‌سازی نخ‌ها به صورت امن فراهم کرده‌اند. توسعه‌دهنده می‌تواند از این ابزارها برای ایجاد برنامه‌های همزمان استفاده کند بدون آنکه نگران شرایط رقابتی (Race Condition) یا بن‌بست (Deadlock) باشد.
در این آموزش، خواننده یاد می‌گیرد که چگونه نخ‌ها را ایجاد و مدیریت کند، دسترسی به منابع مشترک را همگام‌سازی کند، از بن‌بست جلوگیری نماید و کد چندنخی امن و بهینه بنویسد. پس از مطالعه این مطلب، شما قادر خواهید بود تا چندنخی را در پروژه‌های واقعی سی‌پلاس‌پلاس پیاده‌سازی کرده و از الگوهای طراحی و بهینه‌سازی عملکرد بهره‌مند شوید.

مثال پایه

text
TEXT Code
\#include <iostream>
\#include <thread>
\#include <vector>

void printNumbers(int start, int end) {
for (int i = start; i <= end; ++i) {
std::cout << "Thread ID " << std::this_thread::get_id() << ": " << i << std::endl;
}
}

int main() {
std::vector[std::thread](std::thread) threads;

threads.emplace_back(printNumbers, 1, 5);
threads.emplace_back(printNumbers, 6, 10);

for (auto& t : threads) {
if (t.joinable()) {
t.join();
}
}

std::cout << "تمام نخ‌ها به پایان رسیدند." << std::endl;
return 0;

}

در این مثال، از کتابخانه برای ایجاد نخ‌ها، برای مدیریت مجموعه‌ای از نخ‌ها و برای خروجی داده‌ها استفاده شده است. تابع printNumbers اعداد یک بازه را به همراه شناسه نخ چاپ می‌کند تا اجرای همزمان مشاهده شود.
در تابع main()، از std::vectorstd::thread برای ذخیره نخ‌ها استفاده شده و با emplace_back نخ‌ها ایجاد و اجرا می‌شوند. متد joinable() و join() تضمین می‌کند که هر نخ قبل از خاتمه برنامه به پایان برسد. این روش نمونه‌ای از بهترین شیوه‌های برنامه‌نویسی همزمان است، شامل مدیریت امن پارامترها و چرخه عمر نخ‌ها. چاپ شناسه نخ‌ها به درک بهتر اجرای موازی و کاربردی بودن آن در دیباگ و یادگیری کمک می‌کند.

مثال کاربردی

text
TEXT Code
\#include <iostream>
\#include <thread>
\#include <vector>
\#include <mutex>
\#include <numeric>

std::mutex sumMutex;
int globalSum = 0;

void computePartialSum(const std::vector<int>& data, int start, int end) {
int localSum = std::accumulate(data.begin() + start, data.begin() + end, 0);
std::lock_guard[std::mutex](std::mutex) lock(sumMutex);
globalSum += localSum;
}

int main() {
std::vector<int> numbers(1000);
for (int i = 0; i < 1000; ++i) numbers\[i] = i + 1;

std::vector<std::thread> threads;
int chunkSize = numbers.size() / 4;

for (int i = 0; i < 4; ++i) {
int start = i * chunkSize;
int end = (i == 3) ? numbers.size() : start + chunkSize;
threads.emplace_back(computePartialSum, std::cref(numbers), start, end);
}

for (auto& t : threads) {
if (t.joinable()) t.join();
}

std::cout << "مجموع کل اعداد: " << globalSum << std::endl;
return 0;

}

این مثال نشان می‌دهد چگونه می‌توان جمع عناصر یک بردار بزرگ را به صورت امن و موازی محاسبه کرد. تابع computePartialSum مجموع محلی یک بخش از بردار را محاسبه کرده و با استفاده از std::mutex و std::lock_guard به globalSum اضافه می‌کند تا شرایط رقابتی رخ ندهد.
استفاده از std::accumulate محاسبه محلی را بهینه می‌کند و std::cref اجازه می‌دهد مرجع بردار بدون کپی غیرضروری به نخ‌ها منتقل شود. تقسیم بردار به بخش‌های مساوی و اختصاص آن به نخ‌ها نمونه‌ای از بالانس بار و بهینه‌سازی اجرای موازی است. متد joinable() و join() تضمین می‌کند همه نخ‌ها قبل از چاپ نتیجه به پایان برسند. این روش در محاسبات علمی، پردازش تصویر و برنامه‌های مالی که نیازمند پردازش موازی ایمن هستند کاربرد دارد.

بهترین شیوه‌ها در سی‌پلاس‌پلاس برای چندنخی شامل استفاده از std::mutex و std::lock_guard برای محافظت از داده‌های مشترک، استفاده از smart pointer و کانتینرهای استاندارد و مدیریت صحیح چرخه عمر نخ‌ها با join/detach است.
خطاهای رایج شامل شرایط رقابتی، بن‌بست، ایجاد بیش از حد نخ‌ها و موازی‌سازی ناکارآمد الگوریتم‌ها است. برای دیباگ پیشنهاد می‌شود از لاگ دقیق و ابزارهای تخصصی استفاده شود. برای بهینه‌سازی عملکرد، تداخل قفل‌ها را کاهش دهید، از همگام‌سازی غیرضروری پرهیز کنید و وظایف را به طور یکنواخت توزیع نمایید. امنیت شامل کنترل دسترسی به منابع مشترک و جلوگیری از تغییرات ناخواسته در وضعیت برنامه است.

📊 جدول مرجع

سی‌پلاس‌پلاس Element/Concept Description Usage Example
std::thread نمایش یک نخ اجرایی std::thread t(func, arg1);
std::mutex محافظت از داده‌های مشترک std::mutex mtx; std::lock_guard[std::mutex](std::mutex) lock(mtx);
std::lock_guard مدیریت خودکار قفل std::lock_guard[std::mutex](std::mutex) guard(mtx);
std::vector ذخیره داینامیک نخ‌ها std::vector[std::thread](std::thread) threads;
std::accumulate محاسبه مجموع یک بازه int sum = std::accumulate(v.begin(), v.end(), 0);

چندنخی امکان ایجاد برنامه‌های واکنش‌گرا و با عملکرد بالا را فراهم می‌کند. مفاهیم کلیدی شامل ایجاد و مدیریت نخ‌ها، همگام‌سازی منابع مشترک و ادغام الگوریتم‌های استاندارد است.
گام‌های بعدی شامل مطالعه مدل‌های پیشرفته همزمانی، ساختارهای lock-free، Thread Pool و الگوریتم‌های موازی است. تمرین در پروژه‌های واقعی و مراجعه به مستندات رسمی سی‌پلاس‌پلاس باعث تثبیت یادگیری و توسعه برنامه‌های چندنخی مقیاس‌پذیر می‌شود.

🧠 دانش خود را بیازمایید

آماده شروع

Test Your Knowledge

Test your understanding of this topic with practical questions.

4
سوالات
🎯
70%
برای قبولی
♾️
زمان
🔄
تلاش‌ها

📝 دستورالعمل‌ها

  • هر سوال را با دقت بخوانید
  • بهترین پاسخ را برای هر سوال انتخاب کنید
  • می‌توانید آزمون را هر چند بار که می‌خواهید تکرار کنید
  • پیشرفت شما در بالا نمایش داده می‌شود