دوستان متاسفانه دیگه فعالیت نخواهیم داشت😔
این کانال هم داشته باشید به عنوان آخرین پست کانال(حداقل از طرف بنده)
https://www.youtube.com/@iotwithiman/
پلی لیست کامل آموزش STM32 و سیستم های کنترل دیجیتال
این کانال هم داشته باشید به عنوان آخرین پست کانال(حداقل از طرف بنده)
https://www.youtube.com/@iotwithiman/
پلی لیست کامل آموزش STM32 و سیستم های کنترل دیجیتال
YouTube
IoT with Iman
I am Iman. I have investigated the Internet of Things systems for years and have become a full-stack developer: Designing the hardware, develop the device, connect it to a server, and providing its data to an end-user. I am here to share everything I've learned…
💔4
برای آموزش QML هم Downloadly یه سری دوره از Udemy آپلود کرده با عناوین
Qt6 and Qml for begginers
Qt6 and Qml for Intermediate
Qt6 and Qml for Advanced
بنظرم خوب هستن
#cpp
#qt
#programming
Qt6 and Qml for begginers
Qt6 and Qml for Intermediate
Qt6 and Qml for Advanced
بنظرم خوب هستن
#cpp
#qt
#programming
❤2
همزمانی در سیپلاسپلاس
پست یک
خب سیپلاسپلاس و stl یه مجموعه کاملی برای concurrency دارن.
مهم ترینش شاید بشه گفت کلاس std::thread باشه که ریسورسای لازم یک ثرد رو از سیستم عامل میگیره. فرض کنین بخوایم یه تابع رو به شکل همزمان اجرا کنیم شکل کلی برنامه اینجوری میشه:
نکته های خیلی زیادی داره این چندخط که سعی میکنم چندتاشو بگم
۱) یه آبجکت ثرد به محض ساخته شدن، شروع به اجرا میکنه و با stl تاجایی که بنده میدونم نمیتونیم ثردی که از اول ساسپند شده بسازیم
۲) بعد از اینکه به آبجکت از std::thread میسازیم، یا باید joinاش رو صدا کنیم تا ثرد اصلی تا موقع تموم شدن کارش صبر کنه یا detach رو صدا کنیم تا ثرد بره توی پس زمینه اجراشه (کنترل ثرد بیوفته دست کتابخانه رانتایم cpp).
حالا سوال اینه اگه جوین یا دیتچ رو صدا نکنیم چه اتفاقی میوفته؟
اتفاقای بد
خیلی بد😂
۳) توی دیستراکتور thread، اگه یه ثرد جوین یا دیتچ نشده باشه، تابع std::terminate صدا زده میشه که کلا برنامه رو میبنده پس حتما باید قبل از ازبین رفتن آبجکت یکی از ایندوتا تابع رو صدا بزنیم. (یکی از جاهایی که مهمه حواسمون به این نکته باشه، وقتیه که بین ساختن آبجکت و جوین یا دیتچ کردنش یه کد داشته باشیم که exception تولید کنه اینجورجاها بهتره از std::jthread استفاده کنیم. توضیحش خارج از این پسته)
۴) یه ثرد وقتی join یا detachاش صدا زده میشه، تابع std::thread::joinable اش دیگه تا ابد false برمیگردونه. دلیلش سادست. اگه join رو صدا زده باشیم و بعدش joinable رو، قاعدتا تا ثرد تموم نشه، به joinable نمیرسیم و وقتی برسیم ثرد تموم شده و دیگه وجود نداره که بخوایم جوینش کنیم. اگه دیتچ کرده باشیم هم یه ثرد داریم که دیگه دست ما نیست کنترلش و کلا هیچ کنترلی روش نخواهیم داشت. پس باز هم منطقیه که joinable فالس برگردونه.
درواقع دیستراکتور std::thread هم از همین تابع استفاده میکنه تا چک کنه ببینه باید terminate کنه یا نه
۵) اگه تابعی که قراره به صورت همزمان اجرا بشه یه سری متغیر ورودی داشته باشه، توی std::thread این متغیرا رو پاس میدیم ولی باید حواسمون باشه که متغیرها کپی خواهند شد. حتی اگه رفرنس باشن🥸
این یه سری نکته داره که ایشالا بعدا میگم
ادامه
#programming
#cpp
#concurrency
پست یک
خب سیپلاسپلاس و stl یه مجموعه کاملی برای concurrency دارن.
مهم ترینش شاید بشه گفت کلاس std::thread باشه که ریسورسای لازم یک ثرد رو از سیستم عامل میگیره. فرض کنین بخوایم یه تابع رو به شکل همزمان اجرا کنیم شکل کلی برنامه اینجوری میشه:
#include <thread>
void someConcurrentFunction(){}
int main(){
auto th=std::thread(someFunction);
th.join(); //or th.detach()
}
نکته های خیلی زیادی داره این چندخط که سعی میکنم چندتاشو بگم
۱) یه آبجکت ثرد به محض ساخته شدن، شروع به اجرا میکنه و با stl تاجایی که بنده میدونم نمیتونیم ثردی که از اول ساسپند شده بسازیم
۲) بعد از اینکه به آبجکت از std::thread میسازیم، یا باید joinاش رو صدا کنیم تا ثرد اصلی تا موقع تموم شدن کارش صبر کنه یا detach رو صدا کنیم تا ثرد بره توی پس زمینه اجراشه (کنترل ثرد بیوفته دست کتابخانه رانتایم cpp).
حالا سوال اینه اگه جوین یا دیتچ رو صدا نکنیم چه اتفاقی میوفته؟
اتفاقای بد
خیلی بد😂
۳) توی دیستراکتور thread، اگه یه ثرد جوین یا دیتچ نشده باشه، تابع std::terminate صدا زده میشه که کلا برنامه رو میبنده پس حتما باید قبل از ازبین رفتن آبجکت یکی از ایندوتا تابع رو صدا بزنیم. (یکی از جاهایی که مهمه حواسمون به این نکته باشه، وقتیه که بین ساختن آبجکت و جوین یا دیتچ کردنش یه کد داشته باشیم که exception تولید کنه اینجورجاها بهتره از std::jthread استفاده کنیم. توضیحش خارج از این پسته)
۴) یه ثرد وقتی join یا detachاش صدا زده میشه، تابع std::thread::joinable اش دیگه تا ابد false برمیگردونه. دلیلش سادست. اگه join رو صدا زده باشیم و بعدش joinable رو، قاعدتا تا ثرد تموم نشه، به joinable نمیرسیم و وقتی برسیم ثرد تموم شده و دیگه وجود نداره که بخوایم جوینش کنیم. اگه دیتچ کرده باشیم هم یه ثرد داریم که دیگه دست ما نیست کنترلش و کلا هیچ کنترلی روش نخواهیم داشت. پس باز هم منطقیه که joinable فالس برگردونه.
درواقع دیستراکتور std::thread هم از همین تابع استفاده میکنه تا چک کنه ببینه باید terminate کنه یا نه
۵) اگه تابعی که قراره به صورت همزمان اجرا بشه یه سری متغیر ورودی داشته باشه، توی std::thread این متغیرا رو پاس میدیم ولی باید حواسمون باشه که متغیرها کپی خواهند شد. حتی اگه رفرنس باشن🥸
این یه سری نکته داره که ایشالا بعدا میگم
ادامه
#programming
#cpp
#concurrency
Stuff for Geeks
همزمانی در سیپلاسپلاس پست یک خب سیپلاسپلاس و stl یه مجموعه کاملی برای concurrency دارن. مهم ترینش شاید بشه گفت کلاس std::thread باشه که ریسورسای لازم یک ثرد رو از سیستم عامل میگیره. فرض کنین بخوایم یه تابع رو به شکل همزمان اجرا کنیم شکل کلی برنامه اینجوری…
همزمانی در سیپلاسپلاس
پست ۲
تو این پست میخوام در مورد مشکلی که آخر پست یک بهش اشاره شد، بگم. مشکلی که ما با پاس دادن متغیر به std::thread که یه کانستراکتور هست، داریم. فرض کنید که یه تابع مثل زیر داریم و میخوایم اون رو به std::thread پاس بدیم:
خب حالا فرض کنید یه ثرد با این تابع بسازیم:
این کد مشکل ساز خواهد بود
هرچند که اینجا کار میکنه، ولی در ادامه میبینیم که این کد مشکلات بزرگی داره
دلیلش اینه که متنی که داخل دابل کوت قرار داره، یه آبجکت استرینگ نیست و درحقیقت یه
درواقع someFunction یه استرینگ میگیره ولی متد std::thread یه سری ورودی میگیره که جنسشون ربطی به اینکه جنس پارامترهای someFunction چیه نداره. پس اینجا به مشکل میخوریم. مشکل وقتی جدی میشه که پارامتری که داریم به std::thread پاس میدیم، یه پوینتر اتوماتیک باشه که از اسکوپ خارج شده باشه ولی ثرد بهش نیاز داشته باشه. اینجاست که کدمون خطری میشه.
راه حل چیه؟
راه حل اینه که واضحا به کامپایلر بگیم که میخوایم استرینگ پاس بدیم. کد زیر، کد درسته:
همین قضیه برای رفرنس برقراره. البته ایندفعه کامپایلر ارور میده. مثلا کد زیر، خطای کامپایل خواهد داشت:
اینجا هم باید به کامپایلر واضح بگیم که باید رفرنس پاس بده. برای اینکار باید از std::ref استفاده کنیم که یه wrapper برای reference هست:
و کد کامپایل خواهد شد.
ادامه
#programming
#cpp
#concurrency
پست ۲
تو این پست میخوام در مورد مشکلی که آخر پست یک بهش اشاره شد، بگم. مشکلی که ما با پاس دادن متغیر به std::thread که یه کانستراکتور هست، داریم. فرض کنید که یه تابع مثل زیر داریم و میخوایم اون رو به std::thread پاس بدیم:
void someFunction(std::string someString){
//some processing
}خب حالا فرض کنید یه ثرد با این تابع بسازیم:
int main(){
std::thread th(someFunction, "some string");
th.join();
return 0;
}این کد مشکل ساز خواهد بود
هرچند که اینجا کار میکنه، ولی در ادامه میبینیم که این کد مشکلات بزرگی داره
دلیلش اینه که متنی که داخل دابل کوت قرار داره، یه آبجکت استرینگ نیست و درحقیقت یه
cons char* عه.درواقع someFunction یه استرینگ میگیره ولی متد std::thread یه سری ورودی میگیره که جنسشون ربطی به اینکه جنس پارامترهای someFunction چیه نداره. پس اینجا به مشکل میخوریم. مشکل وقتی جدی میشه که پارامتری که داریم به std::thread پاس میدیم، یه پوینتر اتوماتیک باشه که از اسکوپ خارج شده باشه ولی ثرد بهش نیاز داشته باشه. اینجاست که کدمون خطری میشه.
راه حل چیه؟
راه حل اینه که واضحا به کامپایلر بگیم که میخوایم استرینگ پاس بدیم. کد زیر، کد درسته:
int main(){
std::thread th(someFunction, std::string("some string"));
th.join();
return 0;
}همین قضیه برای رفرنس برقراره. البته ایندفعه کامپایلر ارور میده. مثلا کد زیر، خطای کامپایل خواهد داشت:
void foo(int& someRef){
//...
}
int main(){
int i=10;
std::thread th(foo, i);
th.join();
return 0;
}اینجا هم باید به کامپایلر واضح بگیم که باید رفرنس پاس بده. برای اینکار باید از std::ref استفاده کنیم که یه wrapper برای reference هست:
void foo(int& someRef){
//...
}
int main(){
int i=10;
std::thread th(foo, std::ref(i));
th.join();
return 0;
}و کد کامپایل خواهد شد.
ادامه
#programming
#cpp
#concurrency
Simplified designing of analog and digital filters, op-amps and amplifiers and more:
https://youtube.com/@adanner
https://youtube.com/@adanner
A great channel
C/C++ Programming
OpenGL and SDL2/3
SFML
Design Patterns
and much more
https://www.youtube.com/@MikeShah
C/C++ Programming
OpenGL and SDL2/3
SFML
Design Patterns
and much more
https://www.youtube.com/@MikeShah
YouTube
Mike Shah
Teaching computer Science, primarily Modern C++, C, DLang, games, and computer graphics programming
I'm a teaching professor and Senior 3D Graphics Engineer who has worked in industry at various games and graphics companies.
Access Full Courses: courses.mshah.io…
I'm a teaching professor and Senior 3D Graphics Engineer who has worked in industry at various games and graphics companies.
Access Full Courses: courses.mshah.io…
Stuff for Geeks
همزمانی در سیپلاسپلاس پست ۲ تو این پست میخوام در مورد مشکلی که آخر پست یک بهش اشاره شد، بگم. مشکلی که ما با پاس دادن متغیر به std::thread که یه کانستراکتور هست، داریم. فرض کنید که یه تابع مثل زیر داریم و میخوایم اون رو به std::thread پاس بدیم: void som…
همزمانی در سیپلاسپلاس
پست ۳
تو این پست میخوام درمورد std::jthread که از C++17 به stl اضافه شده یه صبحتی بکنیم.
این کلاس یه خاصیت خوب داره:
توی دیستراکتورش، چک میکنه اگه ثرد جوین نشده بود جوینش میکنه.
چرا این خاصیت خوبه؟
چون ما معمولا یه ثرد که میسازیم، چندین خط بعد جوین یا دیتچش میکنم و به همین دلیل ممکنه بین ساختنش تا جوین شدنش اکسپشن رخ بده یا اتفاقای دیگه که باعث شده ثرد جوین نشه. و همونطور که قبلا گفتیم، اگه یه ثرد عادی (std::thread) جوین نشه و دیستراکتورش صدا زده بشه، برنامه کامل بسته میشه(std::terminate).
پس خوبه که بجای std::thread که توی C++11 اضافه شد، از std::jthread استفاده کنیم.
ادامه
#cpp
#programming
#comcurrency
پست ۳
تو این پست میخوام درمورد std::jthread که از C++17 به stl اضافه شده یه صبحتی بکنیم.
این کلاس یه خاصیت خوب داره:
توی دیستراکتورش، چک میکنه اگه ثرد جوین نشده بود جوینش میکنه.
چرا این خاصیت خوبه؟
چون ما معمولا یه ثرد که میسازیم، چندین خط بعد جوین یا دیتچش میکنم و به همین دلیل ممکنه بین ساختنش تا جوین شدنش اکسپشن رخ بده یا اتفاقای دیگه که باعث شده ثرد جوین نشه. و همونطور که قبلا گفتیم، اگه یه ثرد عادی (std::thread) جوین نشه و دیستراکتورش صدا زده بشه، برنامه کامل بسته میشه(std::terminate).
پس خوبه که بجای std::thread که توی C++11 اضافه شد، از std::jthread استفاده کنیم.
ادامه
#cpp
#programming
#comcurrency
Stuff for Geeks
همزمانی در سیپلاسپلاس پست ۳ تو این پست میخوام درمورد std::jthread که از C++17 به stl اضافه شده یه صبحتی بکنیم. این کلاس یه خاصیت خوب داره: توی دیستراکتورش، چک میکنه اگه ثرد جوین نشده بود جوینش میکنه. چرا این خاصیت خوبه؟ چون ما معمولا یه ثرد که میسازیم،…
همزمانی در سیپلاسپلاس
پست ۴
خب
حالا که چندین ثرد داریم، اگه خواسته باشیم یه حافظهای بین اینا به اشتراک بذاریم(shared_momry) باید چیکار کنیم؟
تعداد زیادی از مشکلات و مباحث همزمانی از اینجا شروع میشه.
مشکل اول، race condition:
یه مثال معروفی هست برای اینکه بفهمیم این مشکل چیه. فرض کنید رفتین سینما یا تئاتر و دهتا از مسئولین سالن دارن برای هر صندلی بلیت میفروشن. (صندلیها میشن shared memory و ماموران فروش میشن ثردها)
حالا اینجا مشکل اولی که پیش میاد اینه که اگه ماموران فروش خوب هماهنگ نشده باشن، ممکنه یه صندلی رو به دو یا چندتانفر بفروشن که قاعدتا کار اشتباهیه
اینجا هم همین مشکل هست
فرض کنید دوتا ثرد بخوان به عددی که تو یه خونه از حافظه هست رو بخونن(read) و مقدارش رو یک واحد اضافه کنن(write).
این مورد هم توجه داشته باشید که دیتا متاسفانه کش میشه. ینی از مموری اصلی(رم) خونده میشه و تا یه مدت کوتاهی توی سی پی یو هست.
حالا فرض کنید مقداری که توی حافظه هست عدد ده باشه.
ثرد یک این مقدار رو میخونه(۱۰) و این مقدار خونده شده میاد تو کش.
میاد یکی بهش اضافه کنه ولی تا بخواد اضافه کنه، ثرد دو چون همزمان داره اجرا میشه، ممکنه بیاد و بخواد عملیات خوندن رو انجام بده و چون توی کش مقدار ده رو داریم، عدد ده رو خواهد خوند. بعد هر ثرد یکی اضافه میکنن به این مقدار که میشه یازده و توی مموری مینویسنش.
انتظارمون این بود به عدد دوازده توی مموری برسیم(چون دوتا ثرد هرکدوم داشتن به یه متغیر یه واحد اضافه میکردن) ولی ممکنه به عدد یازده هم برسیم.
برای رفع این مشکل ساختارهای متفاوتی در سطح نرمافزاری و سخت افزاری داریم. در سطح نرمافزاری یا دقیق تر سیستم عاملی، mutex و semaphore و در سطح سختافزاری atomic operation ها رو داریم که در ادامه بررسی خواهند شد
ادامه
#programming
#cpp
#comcurrency
پست ۴
خب
حالا که چندین ثرد داریم، اگه خواسته باشیم یه حافظهای بین اینا به اشتراک بذاریم(shared_momry) باید چیکار کنیم؟
تعداد زیادی از مشکلات و مباحث همزمانی از اینجا شروع میشه.
مشکل اول، race condition:
یه مثال معروفی هست برای اینکه بفهمیم این مشکل چیه. فرض کنید رفتین سینما یا تئاتر و دهتا از مسئولین سالن دارن برای هر صندلی بلیت میفروشن. (صندلیها میشن shared memory و ماموران فروش میشن ثردها)
حالا اینجا مشکل اولی که پیش میاد اینه که اگه ماموران فروش خوب هماهنگ نشده باشن، ممکنه یه صندلی رو به دو یا چندتانفر بفروشن که قاعدتا کار اشتباهیه
اینجا هم همین مشکل هست
فرض کنید دوتا ثرد بخوان به عددی که تو یه خونه از حافظه هست رو بخونن(read) و مقدارش رو یک واحد اضافه کنن(write).
این مورد هم توجه داشته باشید که دیتا متاسفانه کش میشه. ینی از مموری اصلی(رم) خونده میشه و تا یه مدت کوتاهی توی سی پی یو هست.
حالا فرض کنید مقداری که توی حافظه هست عدد ده باشه.
ثرد یک این مقدار رو میخونه(۱۰) و این مقدار خونده شده میاد تو کش.
میاد یکی بهش اضافه کنه ولی تا بخواد اضافه کنه، ثرد دو چون همزمان داره اجرا میشه، ممکنه بیاد و بخواد عملیات خوندن رو انجام بده و چون توی کش مقدار ده رو داریم، عدد ده رو خواهد خوند. بعد هر ثرد یکی اضافه میکنن به این مقدار که میشه یازده و توی مموری مینویسنش.
انتظارمون این بود به عدد دوازده توی مموری برسیم(چون دوتا ثرد هرکدوم داشتن به یه متغیر یه واحد اضافه میکردن) ولی ممکنه به عدد یازده هم برسیم.
برای رفع این مشکل ساختارهای متفاوتی در سطح نرمافزاری و سخت افزاری داریم. در سطح نرمافزاری یا دقیق تر سیستم عاملی، mutex و semaphore و در سطح سختافزاری atomic operation ها رو داریم که در ادامه بررسی خواهند شد
ادامه
#programming
#cpp
#comcurrency
Another youtube channel:
Cryptocurrency(16h) Networking(28h)
ML(52h)
DL(21h)
Advanced PowerShell(12h)
And more
https://youtube.com/@nerdslesson
#programming
#network
#course
Cryptocurrency(16h) Networking(28h)
ML(52h)
DL(21h)
Advanced PowerShell(12h)
And more
https://youtube.com/@nerdslesson
#programming
#network
#course
Stuff for Geeks
همزمانی در سیپلاسپلاس پست ۴ خب حالا که چندین ثرد داریم، اگه خواسته باشیم یه حافظهای بین اینا به اشتراک بذاریم(shared_momry) باید چیکار کنیم؟ تعداد زیادی از مشکلات و مباحث همزمانی از اینجا شروع میشه. مشکل اول، race condition: یه مثال معروفی هست برای اینکه…
همزمانی در سیپلاسپلاس
پست ۵
توی این پست میخوام درمورد mutex صحبت کنم. توی پست قبلی گفتیم که دسترسی چند ثرد به یه ریسورس، مشکلساز میشه و باید کنترل شه. یکی از ابزارهامون همین mutex هست. با mutex میتونیم قسمتهایی از کد که با یک shared memory کار دارن رو بهشون یه برچسب بزنیم و بگیم که این تیکه باید توسط یک ثرد کامل انجام بشه و تا انجام نشده ثرد دیگهای نباید مداخله کنه. اینجوری یه بخشی از مشکلات حل میشه. درواقع mutex مخفف mutual exclusive هست که همین قضیه رو نشون میده.
به اون تیکه از کد که برچسب زدیم بهش هم، critical section میگن.
استفاده از میوتکس توی سیپلاسپلاس راحته ولی باید طراحی همزمانی با وسواس و دقت زیادی انجام بشه چون صرف استفاده از میوتکس، دلیل بر رفع مشکل مخصوصا مشکلات طراحی نمیشه.
خب فرض کنید میخوایم یه تیکه از کد رو بگیم که mutual exclusive هست. اینجوری میشه:
البته چون لاک و آنلاک کردن دستی میوتکس یه آنتیپترن حساب میشه، یه سری کلاسهای دیگه مثل lock_gaurd داریم که یه میوتکس میگیره، لاک میکنه و با خارج شدن از اسکوپ، اون رو آنلاک میکنه.
یعنی کد بالا با lock_gaurd به شکل زیر تغییر میکنه:
و چندین کلاس دیگه هم داریم. مثلا scoped_lock که توی C++17 اضافه شده، نسخه بهتر lock_gaurd حساب میشه. این کلاس یک یا چندتا میوتکس میگیره و جوری لاک و آنلاکشون میکنه که dead lock پیش نیاد.
حالا dead lock چیه؟
اگه دوتا ریسورس r1 و r2 و میوتکسهای m1 و m2 رو داشته باشیم و دوتا ثرد t1 و t2 که به این ریسورسها نیاز دارن، اگه ترتیب لاک و آنلاک شدن بد باشه به ددلاک میخوریم.
مثلا t1 به r2 نیاز داره که توسط m2 و t2 لاک شده و شرط آنلاک شدنش دسترسی به r1 عه درحالیکه r1 توسط m1 و t1 لاک شده.
اینجاست که هیچ وقت ریسورسها آنلاک نمیشن و ثردها تا همیشه تو صف انتظار میمونن!
پس scoped_lock این مشکل رو حل میکنه ولی بازم تاکید میکنم که استفاده از میوتکس خوب و درسته درصورتیکه طراحی درست باشه
توی پست بعدی درمورد طراحی اشتباه و مشکلاتش صحبت میکنم
ادامه
#cpp
#concurrency
#programming
پست ۵
توی این پست میخوام درمورد mutex صحبت کنم. توی پست قبلی گفتیم که دسترسی چند ثرد به یه ریسورس، مشکلساز میشه و باید کنترل شه. یکی از ابزارهامون همین mutex هست. با mutex میتونیم قسمتهایی از کد که با یک shared memory کار دارن رو بهشون یه برچسب بزنیم و بگیم که این تیکه باید توسط یک ثرد کامل انجام بشه و تا انجام نشده ثرد دیگهای نباید مداخله کنه. اینجوری یه بخشی از مشکلات حل میشه. درواقع mutex مخفف mutual exclusive هست که همین قضیه رو نشون میده.
به اون تیکه از کد که برچسب زدیم بهش هم، critical section میگن.
استفاده از میوتکس توی سیپلاسپلاس راحته ولی باید طراحی همزمانی با وسواس و دقت زیادی انجام بشه چون صرف استفاده از میوتکس، دلیل بر رفع مشکل مخصوصا مشکلات طراحی نمیشه.
خب فرض کنید میخوایم یه تیکه از کد رو بگیم که mutual exclusive هست. اینجوری میشه:
#include <mutex>
using std::mutex;
int main(){
mutex m1;
...
//Start of critical section
m1.lock()
...
m1.unlock()
//End of critical section
}
البته چون لاک و آنلاک کردن دستی میوتکس یه آنتیپترن حساب میشه، یه سری کلاسهای دیگه مثل lock_gaurd داریم که یه میوتکس میگیره، لاک میکنه و با خارج شدن از اسکوپ، اون رو آنلاک میکنه.
یعنی کد بالا با lock_gaurd به شکل زیر تغییر میکنه:
//Start of critical section
{
lock_gaurd lock1{m1} //m1 is locked now
}
//End of critical section
//m1 gets unlocked in lock1 destructor (RAII)
و چندین کلاس دیگه هم داریم. مثلا scoped_lock که توی C++17 اضافه شده، نسخه بهتر lock_gaurd حساب میشه. این کلاس یک یا چندتا میوتکس میگیره و جوری لاک و آنلاکشون میکنه که dead lock پیش نیاد.
حالا dead lock چیه؟
اگه دوتا ریسورس r1 و r2 و میوتکسهای m1 و m2 رو داشته باشیم و دوتا ثرد t1 و t2 که به این ریسورسها نیاز دارن، اگه ترتیب لاک و آنلاک شدن بد باشه به ددلاک میخوریم.
مثلا t1 به r2 نیاز داره که توسط m2 و t2 لاک شده و شرط آنلاک شدنش دسترسی به r1 عه درحالیکه r1 توسط m1 و t1 لاک شده.
اینجاست که هیچ وقت ریسورسها آنلاک نمیشن و ثردها تا همیشه تو صف انتظار میمونن!
پس scoped_lock این مشکل رو حل میکنه ولی بازم تاکید میکنم که استفاده از میوتکس خوب و درسته درصورتیکه طراحی درست باشه
توی پست بعدی درمورد طراحی اشتباه و مشکلاتش صحبت میکنم
ادامه
#cpp
#concurrency
#programming
Forwarded from Sisoog مرجع متن باز الکترونیک-سیسوگ
یه خبر هیجانانگیز برای عاشقان گجتهای خفن دارم!
اگه اسم Flipper Zero به گوشت خورده باشه، میدونی که این ابزار یه مولتیتول محبوب بین هکرهای سختافزار و متخصصین تست نفوذ هست. ولی خب، قیمتش همیشه یه چالش بوده. حالا یه پروژه متنباز به اسم CapibaraZero اومده که با استفاده از سختافزارهای ارزونتر مبتنی بر ESP32-S3 مثل LilyGO T-Embed CC1101، یه جایگزین اقتصادی برای Flipper Zero ارائه میده!
چی باعث میشه CapibaraZero خاص باشه؟
متنباز بودن نرم افزار و این که روی سختافزارهایی مثل LilyGO T-Embed CC1101 اجرا میشه. این سختافزار امکانات فوقالعادهای داره:
- پردازنده دو هستهای ESP32-S3.
- اتصال WiFi 4 و Bluetooth 5.0.
- پشتیبانی از فرکانسهای Sub-GHz برای کنترل از راه دور.
- ماژول NFC/RFID برای کاربردهای متنوع.
- نمایشگر رنگی 1.9 اینچی و باتری 1300 میلیآمپری.
- امکانات اضافی مثل IR، دکمههای کنترلی، و حتی چراغهای RGB!
چرا این پروژه جذابه؟
در واقع Flipper Zero که به خاطر قابلیتهای جذابش حسابی مشهور شده، همیشه قیمت بالایی داشته (حدود 169 دلار). در حالی که سختافزارهایی مثل LilyGO فقط با 60-70 دلار قابل خرید هستن. CapibaraZero هم قابلیتهایی مثل Wi-Fi، NFC، Sub-GHz، و حملات شبکه رو فراهم کرده و همچنان در حال گسترش قابلیتهاشه :).
از کجا میتونی شروع کنی؟
برای اجرای CapibaraZero، میتونی از بردهای مثل Arduino Nano ESP32 یا ESP32-S3-DevKitC-1 هم استفاده کنی، ولی برای امکانات کاملتر، LilyGO T-Embed CC1101 گزینه بهتریه.
این یعنی اگه همیشه دنبال یه ابزار چندمنظوره مثل Flipper Zero بودی ولی نمیخواستی زیاد هزینه کنی، حالا وقتشه. چه کسی میدونه، شاید این همون گجت رویایی باشه که دنبالش بودی! 😊
#0x7a657573 #sisoog #hack #iot
اگه اسم Flipper Zero به گوشت خورده باشه، میدونی که این ابزار یه مولتیتول محبوب بین هکرهای سختافزار و متخصصین تست نفوذ هست. ولی خب، قیمتش همیشه یه چالش بوده. حالا یه پروژه متنباز به اسم CapibaraZero اومده که با استفاده از سختافزارهای ارزونتر مبتنی بر ESP32-S3 مثل LilyGO T-Embed CC1101، یه جایگزین اقتصادی برای Flipper Zero ارائه میده!
چی باعث میشه CapibaraZero خاص باشه؟
متنباز بودن نرم افزار و این که روی سختافزارهایی مثل LilyGO T-Embed CC1101 اجرا میشه. این سختافزار امکانات فوقالعادهای داره:
- پردازنده دو هستهای ESP32-S3.
- اتصال WiFi 4 و Bluetooth 5.0.
- پشتیبانی از فرکانسهای Sub-GHz برای کنترل از راه دور.
- ماژول NFC/RFID برای کاربردهای متنوع.
- نمایشگر رنگی 1.9 اینچی و باتری 1300 میلیآمپری.
- امکانات اضافی مثل IR، دکمههای کنترلی، و حتی چراغهای RGB!
چرا این پروژه جذابه؟
در واقع Flipper Zero که به خاطر قابلیتهای جذابش حسابی مشهور شده، همیشه قیمت بالایی داشته (حدود 169 دلار). در حالی که سختافزارهایی مثل LilyGO فقط با 60-70 دلار قابل خرید هستن. CapibaraZero هم قابلیتهایی مثل Wi-Fi، NFC، Sub-GHz، و حملات شبکه رو فراهم کرده و همچنان در حال گسترش قابلیتهاشه :).
از کجا میتونی شروع کنی؟
برای اجرای CapibaraZero، میتونی از بردهای مثل Arduino Nano ESP32 یا ESP32-S3-DevKitC-1 هم استفاده کنی، ولی برای امکانات کاملتر، LilyGO T-Embed CC1101 گزینه بهتریه.
این یعنی اگه همیشه دنبال یه ابزار چندمنظوره مثل Flipper Zero بودی ولی نمیخواستی زیاد هزینه کنی، حالا وقتشه. چه کسی میدونه، شاید این همون گجت رویایی باشه که دنبالش بودی! 😊
#0x7a657573 #sisoog #hack #iot
این اکانت در ایکس(توییتر سابق) منابع بسیار زیاد و بسیار خوبی میذاره:
https://x.com/chessMan786
مثلا:
https://youtube.com/playlist?list=PL-Mfq5QS-s8iUJpNzCOtQKRfpswCrPbiW
https://x.com/chessMan786
مثلا:
https://youtube.com/playlist?list=PL-Mfq5QS-s8iUJpNzCOtQKRfpswCrPbiW
X (formerly Twitter)
Mohit Mishra (@chessMan786) on X
engineer | engineering | learning to learn the low-level system
👍1
push_back(c++11)?
emplace_back(c++17)?
مسئله اینست
فرض کنید که یک کلاس با تعداد زیادی فیلد(سایز زیاد) داریم و میخوایم یه وکتور از این تایپ داشته باشیم:
خب حالا چجوری داخل یه وکتور اشیائی ازین کلاس رو وارد کنیم؟
آیا پوش بک بهینست؟
برای جواب به این سوال، فرض کنید یه شیئ ساخته شده از کلاس حجیممون داریم. مثلا اسمش b باشه. وکتورمون هم فرضا v باشه، وقتی مینویسیم:
v.push_back(b)
اتفاقی که معمولا میوفته اینه که b کپی میشه و داخل v پوش میشه.
این کپی کردنه مشکل ماجراست که باعث میشه ریسورس زیادی از دست بدیم پس چه کنیم؟
از تابع emplace_back استفاده میکنیم. این تابع، مزیتی که داره اینه که با گرفتن پارامترهای لازم برای ساختن یه شیئ از کلاس مدنظر، اون شیئ رو میسازه و move میکنه داخل وکتور.(اگه نمیدونین move چیه سرچ کنید move semantics)
خلاصه که اینجوری دیگه شیئ اضافی کپی نمیشه و خیالمون راحته.
البته میشه اینجوری هم کار رو درآورد:
v.push_back(std::move(b))
ولی بعد اینکار b از بین میره و دسترسی بهش باعث undefined behavior میشه.
خب پس اگه لازم بود شیئ بسازین و داخل وکتور قرار بدین، همیشه emplace_back بهتر از push_back خواهد بود.
#cpp
#programming
emplace_back(c++17)?
مسئله اینست
فرض کنید که یک کلاس با تعداد زیادی فیلد(سایز زیاد) داریم و میخوایم یه وکتور از این تایپ داشته باشیم:
class BigStructure{
//lots of fields
//...
};خب حالا چجوری داخل یه وکتور اشیائی ازین کلاس رو وارد کنیم؟
آیا پوش بک بهینست؟
برای جواب به این سوال، فرض کنید یه شیئ ساخته شده از کلاس حجیممون داریم. مثلا اسمش b باشه. وکتورمون هم فرضا v باشه، وقتی مینویسیم:
v.push_back(b)
اتفاقی که معمولا میوفته اینه که b کپی میشه و داخل v پوش میشه.
این کپی کردنه مشکل ماجراست که باعث میشه ریسورس زیادی از دست بدیم پس چه کنیم؟
از تابع emplace_back استفاده میکنیم. این تابع، مزیتی که داره اینه که با گرفتن پارامترهای لازم برای ساختن یه شیئ از کلاس مدنظر، اون شیئ رو میسازه و move میکنه داخل وکتور.(اگه نمیدونین move چیه سرچ کنید move semantics)
خلاصه که اینجوری دیگه شیئ اضافی کپی نمیشه و خیالمون راحته.
البته میشه اینجوری هم کار رو درآورد:
v.push_back(std::move(b))
ولی بعد اینکار b از بین میره و دسترسی بهش باعث undefined behavior میشه.
خب پس اگه لازم بود شیئ بسازین و داخل وکتور قرار بدین، همیشه emplace_back بهتر از push_back خواهد بود.
#cpp
#programming
Stuff for Geeks
push_back(c++11)? emplace_back(c++17)? مسئله اینست فرض کنید که یک کلاس با تعداد زیادی فیلد(سایز زیاد) داریم و میخوایم یه وکتور از این تایپ داشته باشیم: class BigStructure{ //lots of fields //... }; خب حالا چجوری داخل یه وکتور اشیائی ازین کلاس رو وارد…
در همین راستا، خوبه
try_emplace (C++17)
و
std::map::emplace (C++11)
رو که توابعی هستن از std::map
و std::unordered_map بهش یه اشاره بکنیم.
وقتی یه مپ داشته باشیم و بخوایم یه key و value داخلش قرار بدیم، چندتا راه وجود داره
بدترین ولی قدیمی ترین راه:
map[key] = value
خب مشکل ما با این کار اینه که اگه یه key و value از قبل وجود داشته باشن که کلیدش با کلیدی که داریم میدیم یکی باشه، اون value قبلی از بین میره و value جدید جاش میشینه.
راه دوم استفاده از emplace هست که یه std::pair میگیره، key و value رو میسازه و اگه key ساخته شده از قبل وجود نداشت، جفت key و value رو اضافه میکنه به مپ. مشکل ما اینجا اینه که اول key و value ساخته میشن و بعد key تست میشه که توی مپ هست یا نه که این ساخته شدن قبل از تست جالب نیست.
راه سوم استفاده از try_emplace هست. توی این روش، دقیقا مثل emplace ورودی یکسانه ولی فقط key ساخته میشه و چک میشه که داخل مپ نباشه و اگه نبود، value از روی پارامترهای موجود توی مپ ساخته میشه و داخل مپ قرار داده میشه.
راه های دیگه ای هم هست که خیلی واردش نمیشم(مثلا insert) ولی خب چندان تاثیری هم روی بحث الانمون ندارن
پس اگه خواستین توی مپ چیزی قرار بدین، try_emplace رو درنظر بگیرین.
#cpp
#programming
try_emplace (C++17)
و
std::map::emplace (C++11)
رو که توابعی هستن از std::map
و std::unordered_map بهش یه اشاره بکنیم.
وقتی یه مپ داشته باشیم و بخوایم یه key و value داخلش قرار بدیم، چندتا راه وجود داره
بدترین ولی قدیمی ترین راه:
map[key] = value
خب مشکل ما با این کار اینه که اگه یه key و value از قبل وجود داشته باشن که کلیدش با کلیدی که داریم میدیم یکی باشه، اون value قبلی از بین میره و value جدید جاش میشینه.
راه دوم استفاده از emplace هست که یه std::pair میگیره، key و value رو میسازه و اگه key ساخته شده از قبل وجود نداشت، جفت key و value رو اضافه میکنه به مپ. مشکل ما اینجا اینه که اول key و value ساخته میشن و بعد key تست میشه که توی مپ هست یا نه که این ساخته شدن قبل از تست جالب نیست.
راه سوم استفاده از try_emplace هست. توی این روش، دقیقا مثل emplace ورودی یکسانه ولی فقط key ساخته میشه و چک میشه که داخل مپ نباشه و اگه نبود، value از روی پارامترهای موجود توی مپ ساخته میشه و داخل مپ قرار داده میشه.
راه های دیگه ای هم هست که خیلی واردش نمیشم(مثلا insert) ولی خب چندان تاثیری هم روی بحث الانمون ندارن
پس اگه خواستین توی مپ چیزی قرار بدین، try_emplace رو درنظر بگیرین.
#cpp
#programming
دوستان بنده نهایتا تا C++20 دیدم و شنیدم
با احتمال زیاد بهتر ازین اومده توی نسخههای جدید که من خبری ندارم ازشون. پس این رو هم درنظر بگیرین🍄
با احتمال زیاد بهتر ازین اومده توی نسخههای جدید که من خبری ندارم ازشون. پس این رو هم درنظر بگیرین🍄
ایشون ریسورس های خوبی برای توسعه بدافزار و خلاصه امنیت باینری توی گیت هاب و ایکسش داره:
https://x.com/5mukx
#malware
#binary
#security
https://x.com/5mukx
#malware
#binary
#security
👍2