اشتراکها
اشتراکها
استانداردهای کدنویسی #C
اشتراکها
اضافه شدن Async-await به زبان Rust
نظرات مطالب
بررسی Bad code smell ها: کلاس بزرگ
مطلبی رو اینجا دیدم که به نظر طنز هست و مرتبط به مطلب جاری
In the C++ world we don’t create a class witch contains 5 methods and 2
fields like in Java or C#. We do more. A lot more. Our class are
consequent and take a lot of stuff inside because it is interesting to
have a project with 10 files of 100 KB rather than 300 files of 3 KB
organized with fuzzy concepts. We do OOP better. It’s more compact, it’s
real, it just works
برنامه نویسی موازی، نقطهی متقابل برنامه نویسی سریال که حتی گاها با برنامه نویسی سریال به سبک Asynchronous به اشتباه گرفته میشود، به سبکی از برنامه نویسی گفته میشود که در آن برنامه نویس قابلیت اجرای بخشهای موازی برنامه را از طریق چندین Thread و به طور همزمان ایجاد کرده باشد. نکاتی که در این سبک برنامه نویسی بسیار مهم است، مهارتهای برنامه نویس در درک قسمتهای موازی برنامه و مجزا سازی این بخشها از یکدیگر است تا کمترین ارتباط را با هم داشته باشند. مشخصا تمامی یک برنامه قابلیت موازی سازی را نخواهد داشت؛ اما مفهومی به عنوان درجهی موازی سازی در هر برنامه وجود دارد که ایده آل موازی سازی، رسیدن به این درجهی از موازی سازی است.
در برنامه نویسی موازی، قسمتهایی از برنامه که به Threadهای مجزایی برای اجرا محول شدهاند، میتوانند تقریبا در یک زمان شروع به اجرا کنند و اینگونه است که سرعت اجرای عملیات افزایش پیدا میکند. به عنوان مثال فرض کنید برنامهای داریم که ۱۰۰ رکورد از پایگاه داده واکشی میکند و بررسیای بر روی یکی از فیلدهای آن انجام میدهد که ۳ ثانیه زمان گیر است و در صورت وجود شرایط خاصی، آن رکورد را لاگ میکند. در برنامه نویسی سریال، برسی ۱۰۰ رکورد، به ۳۰۰ ثانیه زمان برای انجام احتیاج دارد؛ ولی با فرض انجام همین عملیات با دو Thread به صورت موازی، این زمان تقریبا به نصف کاهش پیدا خوهد کرد.
چرا و در چه زمانی باید به سراغ برنامه نویسی موازی رفت !؟
نرم افزارهای بزرگ با تعداد تراکنشهای بالا و حجم اطلاعات بالا که همواره نیازمند پردازش مستمر هستند، لزوم استفادهی بهینه از قدرت پردازشی پردازندهها را ایجاب میکنند. به طور کل میتوان گفت قسمتهایی از برنامه که عملیات پردازشی را روی دادههای مجزا انجام میدهند، بهترین بخش برای انجام عملیات به صورت موازی و همزمان هستند. البته نباید این نکته را نیز فراموش کرد که عملیات ایجاد Thread و مدیریت آنها، دارای سربار است. ازینرو بهتر است برای کارهای ساده و کوچک، به سراغ برنامه نویسی موازی نرفت.
در اجرای موازی بخشهای مختلف برنامه، ترتیب انجام هر بخش نباید در نتیجهی کلی تاثیر گذار باشد. در عملیات جمع یک مجموعه میتوان آن را به چند Thread مجزا محول کرد تا هر بخش از مجموعه را یک Thread جمع بزند و در نهایت نتیجهی کل Threadها با هم جمع شود. در این عملیات ترتیب اتمام کار هر Thread، نتیجهای بر Threadهای دیگر و نتیجهی نهایی، نخواهد داشت. اما در شکل بالا بعد از اتمام انجام عملیات تبدیل حروف کوچک به بزرگ توسط هر Thread، گارانتیای برای چاپ آنها به همان ترتیبی که از سورس خوانده شدهاند، وجود ندارد. به عبارتی ممکن است در ابتدا وظیفهی 2 Thread تمام شده باشد و بعد 1 Thread که باعث خواهد شد در خروجی، ابتدا کاراکترهای "CD" و سپس "AB" نمایش داده شود. البته این یک مثال ساده برای درک موضوع است.
مفهوم Thread Safe
Thread Safe یک مفهوم مرتبط به زبانهای برنامه نویسی با قابلیت اجرای چند ریسمانی میباشد؛ بدین مفهوم که Thread safe فقط در نرم افزارهایی که به صورت Multi Thread نوشته شدهاند معنا پیدا میکند.درک مفهوم Thread Safe و تکنیکهای مرتبط با آن، در نرم افزارهای چند ریسمانی بسیار حائز اهمیت میباشد. چرا که باعث بروز برخی خطاهای منطقی در عملکرد سیستم خواهد شد که بعضاً ردگیری آنها نیز بسیار دشوار است. به طور کلی هنگامیکه threadهای مختلفی در یک برنامه در حال کار همزمان میباشند، رخ دادن دو اتفاق شایع زیر دور از ذهن نیست:
1- Dead Lock
مفهوم بن بست در علوم کامپیوتر، یکی ار رایجترین مفاهیم است که از سطح سیستم عامل تا سیستمهای توزیع شده، تعمیم داده میشود. Dead Lock زمانی رخ میدهد که Threadهای مختلف، با منابع مشترکی کار میکنند. بدین صورت که Thread شماره ۱، منبع A را در اختیار دارد و منتظر منبع B است. همزمان Thread شماره دو، منبع B را در اختیار دارد و منتظر منبع A است. به این شرایط، بن بست میگویند. شبیه سازی این اتفاق را در کد #C زیر میتوانید ببینید:
public static void Function_A() { lock (resource_1) { Thread.Sleep(1000); lock (resource_ 2) { } } } public static void Function_B() { lock (resource_2) { Thread.Sleep(1000); lock (resource_1) { } } } static void Main() { Thread thread_A = new Thread((ThreadStart)Function_A); Thread thread_B = new Thread((ThreadStart)Function_B); thread_A.Start(); thread_B.Start(); while (true) { // Stare at the two threads in deadlock. } }
2- Race conditions
زمانی رخ میدهد که دو یا چند thread به یک مقدار مشترک دسترسی داشته باشند و تلاش کنند که در یک زمان، مقدار آن را تغییر دهند. مشکل از جایی رخ میدهد که شما به عنوان یک برنامه نویس نمیدانید، در یک زمان یکسان، برای تغییر یه مقدار مشترک بین threadها، اولویت با کدام thread است. این اولویت بندی و جابجایی بین threadها وظیفهی الگوریتم زمان بندی threadها است که در هر زمان میتواند بین threadهای مختلف سوییچ کند. این اولویت بندی میتواند روی عملکرد کد شما تاثیر گذار باشد؛ مخصوصا در بخشهایی که مقدار مشترکی برسی میشوند؛ مانند مثال زیر:
if (x == 5) { y = x * 2; }
اگر بلافاصله بعد از بررسی مقدار متغیر x توسط یک thread ،thread دیگری این مقدار را تغییر دهد، دیگر نتیجهی این بلاک کد، منطقی نخواهد بود و جواب، ۱۰ نخواهد شد.
با توجه به مفاهیم عنوان شده، بررسی Thread safe بودن یک کد، با معیارهای زیر انجام میشود:
۱- قفل گذاری روی منابع باید به شکلی باشد که باعث بروز Dead Lock نشود.
۲- استفاده از مقادیر مشترک باید به گونهای باشد که منجر به Race-conditions نشود.
نظرات اشتراکها
مثالی از کاربرد واژهی dynamic جهت جایگزین کردن آن با DTOs
مطلب تکمیلی
dynamic type
Pros: This approach reduces the need to modify static ViewModel classes whenever you update the SQL sentence of a query, making this design approach pretty agile when coding, straightforward, and quick to evolve in regard to future changes.
Cons: In the long term, dynamic types can negatively impact the clarity and the compatibility of a service with client apps. In addition, middleware software like Swashbuckle cannot provide the same level of documentation on returned types if using dynamic types.
ViewModel (DTO)
Pros : Having static predefined ViewModel classes, like “contracts” based on explicit DTO classes, is definitely better for public APIs but also for long term microservices, even if they are only used by the same application.
If you want to specify response types for Swagger, you need to use explicit DTO classes as the return type. Therefore, predefined DTO classes allow you to offer richer information from Swagger. That improves the API documentation and compatibility when consuming an API.
Cons : As mentioned earlier, when updating the code, it takes some more steps to update the DTO classes.
اشتراکها
سایت ++Modern C
پیشنهادها
C# 7 - Ref Returns and Ref Locals
Ref Returns In C# 7.0
Why ref locals allow only a single binding
C# 7.0 – Ref returns and Locals
C# 7 Feature Proposal: Ref Returns and Locals
C# 7.0 Out Vars and Ref Returns
C#7: Better Performance with Ref Locals, and Ref and Async Returns
مستندات رسمی
Why ref locals allow only a single binding
C# 7.0 – Ref returns and Locals
C# 7 Feature Proposal: Ref Returns and Locals
C# 7.0 Out Vars and Ref Returns
C#7: Better Performance with Ref Locals, and Ref and Async Returns
مستندات رسمی
پیش از ارائه نهایی مطلب، تمام کدهای آن با VS 2017 RTM آزمایش و بررسی شوند.