Thread Safety در C#

Thread Safety در C#

 چندین نخ می توانند به طور همزمان فضایی  را آدرس دهی کنند. آنها می توانند به طور همزمان روی نقطه یکسانی از حافظه بنویسیند. این تعریف یک ویژگی از thread است. این ویژگی thread برای عملکرد خوب نیست.

لذا، thread safety تکنیکی است که ساختار داده مشترک را به صورتی دستکاری می کند که اجرای امن چند نخ به طور همزمان را تضمین کند. به کدی thread safe می گیم که توسط چند نخ به طور همزمان فراخوانی شود اما به عملکرد خدشه ای وارد نکند.

thread safety شرایط زیر را از کد حذف می کند:

Race condition

Deadlocks

Race Condition

به آن race hazard هم می گن. رفتار نرم افزار یا سیستم که خروجی وابسته به ترتیب یا زمبان بندی سایر رویدادهای خارج از کنترل است. زمانی که رویدادها به ترتیبی که مورد نیاز عملکرد است رخ نمی دهند تبدیل به دردسر یا bug می شود.

Race Condition زمانی رخ می دهد که دو thread به یک متغیر به طور همزمان دسترسی دارند. thread اول متغیر را می خواند و thread دوم در همان لحظه آن را مینویسید.

Symptopms of Race Condition

رایج ترین علامت race condition مقادیر خارج از انتظار هستند که بین چندین thread مشترک هستند. در این مواقع گاهی یک thread برنده می شود و گاهی thread های دیگر برنده می شوند. در زمان های دیگر نتیجه اجرا ممکن است درست باشد. هرچند اگر هر thread به طور جداگانه اجرا می شد نتیجه متغیر آن چیزی می شد که انتظار داشتیم.

مثال

دو thread داریم- thread 1 و thread2 و هر دو به طور همزمان اجرا می شوند و lock اعمال نمی شود در نهایت نتیجه اشتباه خواهد بود.

این وضعیت به این خاطر رخ می دهد که lock اعمال نشده و race condition رخ می دهد.

Int myValue = 0;  
Thread1 ---Reads value-------> 0  
Thread2 --Reads Value--------> 0  
Thread1 --Increases value with one and writes back----> 0 +1  
Same time,  
Thread2 --Increases value with one and writes back ------> 0+1  
Final Result = 1  
Expected Result = 2 

جلوگیری از race condition

بهترین رهیافت برای هندل کردن race condition نوشتن کد خیلی دقیق و فعال است. همیشه سعی کنید از lock, mutex, ManualResetEvents و غیره استفاده کنید تا کد را در محیط چند نخی thread safe کنید .

Deadlock

مورد Deadklock در محیط چند نخی یا همرند رخ می دهد. نوعی از وضعیتی است که در آن دو یا چند thread یا وظایفه منتظر thread دیگری می مانند تا پایان بپزیرد و آنها هرگر پایان نمی پذیرند.

در سیستم چند نخی، پردازش موازی و سیستم های توزیع شده مشکل خیلی معروفی است. این مورد اساس با منبع مشترک رخ می دهد. این منبع در این حالت قفل می شود. deadlock توضیح بسیار گسترده ای دارد.

شرایط deadlock

اگر شرط زیر مطابقت داشته باشد، یک شرط بن بست نامیده می شود:

۱- Mutual Exclusion: فقط فرآیند می تواند در زمان معین از منبع استفاده کند.

۲- Hold and wait

۳- No Preemption

۴- Circular Wait

این ۴ شرط به عنوان Coffman Conditions. Edward G. Coffman, Jr. شناخته می شوند. 

روش های thread safe کردن یک object

سه رهیافت برای thread safe کردن شی

۱- synchronize the critical section

۲- make it immutable

۳- use a thread-safe wrapper

سوالات مرتبط با thread -safety

۱- آیا سازنده استاتیک سی شارپ Thread safe است؟

سازنده های Static به طور تضمیمنی فقط یک بار به ازای هر application domain اجرا می شوند، قبل از اینکه هر نمونه ای از کلاس ایجاد شود یا هر عضو static مورد دسترسی قرار بگیرد.

استفاده از سازنده static در واقع thread safe است.

۲- آیا متد static سی شارپ Thread safe است؟

اعضای استاتیک ذاتا thread safe نیستند. CLR با آنها نسبت به متد instance متفاوت برخورد نمی کند.

۳- آیا Delegate به صورت thread safe است؟

modifying event  به صورت thread safe نیست اما فراخوانی delegate به صورت thread safe است. چون delegate یک نوع immutable است پس thread safe است.

منبع

https://www.c-sharpcorner.com/UploadFile/1c8574/thread-safety369/