کداکسپلور | CodeExplore
7.85K subscribers
1.9K photos
269 videos
103 files
1.59K links
با کد اکسپلور یاد بگیر، لذت ببر و بروز باش ⚡️😉

سایت کد‌اکسپلور:
CodeExplore.ir
👨🏻‍💻 ارتباط با ما :
@CodeExploreSup
گروه :
@CodeExplore_Gap
تبلیغات در کد اکسپلور :
@CodeExploreAds
Download Telegram
🚀 اتمیک در ++C — نجات داده‌ها در ازدحام فعالیت تردها!

وقتی در ++C با چند تا ترد همزمان کار می‌کنی، مراقب باش! چون اگر چند تا ترد همزمان به یه متغیر دست بزنن بدون هماهنگی، همه‌چی به هم می‌ریزه. اینجاست که std::atomic به دادت می‌رسه.

🎯 سناریو: شمارش همزمان با تردها
std::atomic_int acnt;
int cnt;

void f() {
for (auto n{10000}; n; --n) {
++acnt; // امن!
++cnt; // خطرناک!
}
}
int main()
{
{
std::vector<std::jthread> pool;
for (int n = 0; n < 10; ++n)
pool.emplace_back(f);
}

std::cout << "The atomic counter is " << acnt << '\n'
<< "The non-atomic counter is " << cnt << '\n';
}

در تابع()f، هر ترد داره ۱۰,۰۰۰ بار یه شمارنده رو زیاد می‌کنه. ولی تفاوت بزرگ اینه که acnt از نوع std::atomic_int هست، ولی cnt یه int معمولیه.
خروجی احتمالی( چون شمارنده معمولی رفتار ثابتی نداره):
The atomic counter is 100000
The non-atomic counter is 69696

چرا اینطوریه؟ چون cnt++ایمن نیست و وقتی چند تا ترد با هم بهش دست می‌زنن، مقدار نهایی اشتباه می‌شه. این یعنی Race Condition.

معنی Race Condition:
حالت Race conditionها (شرایط مسابقه) بیشتر در زمینه‌ی علوم کامپیوتر و برنامه‌نویسی مطرح می‌شن. این مشکل زمانی به وجود میاد که دو پردازه (process) یا ترد (thread) در یک برنامه‌ی کامپیوتری همزمان تلاش می‌کنن به یک منبع مشترک دسترسی پیدا کنن و این باعث بروز اختلال در سیستم می‌شه. Race conditionها یکی از مشکلات رایج در برنامه‌های چندتردی (multithreaded) به شمار میان.

🔍 تفاوت اتمیک و غیراتمیک چیه؟
هر cnt++ در واقع ۳ مرحله داره:

1_خوندن مقدار از RAM

2_اضافه کردن ۱

3_نوشتن مقدار جدید

وقتی چند تا ترد با هم این کارو انجام بدن، ممکنه دو ترد همزمان مقدار رو بخونن، هر دو ۱ اضافه کنن، و هر دو همون مقدار جدید رو ذخیره کنن — یعنی یه شمارش گم می‌شه!

ولی با std::atomic_int، این عملیات به صورت اتمی و همزمانی‌امن (Thread-Safe) انجام می‌شه.

بحثش مفصله. حتی می‌تونید از سطح‌های مختلف memory_order استفاده کنید، مخصوصاً وقتی بین تردها قراره داده به اشتراک گذاشته بشه.
یه راهکار دیگه هم استفاده از std::mutex هست؛ با این روش، یک ترد بخشی از کد رو قفل می‌کنه و بقیه تردها تا زمانی که این قفل باز نشه، اجازه ورود به اون بخش رو ندارن.

منبع: https://en.cppreference.com/w/cpp/atomic/atomic.html

#Cpp #Threads #Atomic #RaceCondition #MultiThreading #Concurrency #برنامه‌نویسی #سی_پلاس_پلاس
☕️Telegram | Website | Discord
❤‍🔥2💔2