За нормальних обставин, якщо використовується багатопотокове програмування, складність програми значно зростає, продуктивність значно знижується, а ймовірність помилок значно зростає.
Багатопотокове програмування призначене для паралельного запуску програми для покращення можливостей обробки даних, але в більшості випадків воно передбачає конкуренцію за спільні ресурси, тому воно має бути заблоковане при зміні об'єктів ресурсів. Однак існує багато способів реалізувати блокування, тому давайте розглянемо реалізацію та продуктивність кількох типів блокувань у C#.
Кілька способів використання замків
1. Атомний замок
Досягти «беззамкової» конкуренції через атомну операцію Interlocked.CompareExchange.
Офіційне пояснення полягає в тому, щоб надати атомарні операції для змінних, спільних для кількох потоків. Простір назв: System.Threading
2. Критична зона
Серіалізація кількох потоків для доступу до публічних ресурсів або коду є швидкою та підходить для контролю доступу до даних. Синтаксис блокування в C# є синтаксичним цукром для критичної області (Monitor).
3. Атомна робота
Атомарні операції, які є особливим випадком, є за своєю природою безпечними потоками, тому немає потреби їх блокувати.
Офіційно інтерпретується як збільшення значення заданої змінної у вигляді атомарної операції та збереження результату. Простір назв: System.Threading
4. Читати і писати замок
Блокування читання-запису дозволяє ресурси для читання, коли інші програми пишуть, тому якщо ресурс дозволяє брудні читання, це більш доречно.
Офіційне пояснення вказує на заблокований стан, який використовується для керування доступом до ресурсів, що дозволяє багатопотокове читання або ексклюзивний доступ до запису. Простір назв — System.Threading
5. Семафор
Семафори, призначені для контролю обмеженої кількості користувацьких ресурсів.
Офіційне пояснення обмежує кількість потоків, які можуть одночасно отримувати доступ до ресурсу або пулу ресурсів. Простір назв — System.Threading
6. Події
Використовується для повідомлення потоку про певні події, що запускає наступне завдання.
Офіційне пояснення стверджує, що події синхронізації потоків автоматично скидаються, коли сигнал отримується після відпуску потоку. Такі типи не можуть бути успадковані.
7. Взаємне виключення
Існує клас Mutex у C#, безпосередньо під простором назв System.Threading, Mutex насправді є м'ютексом, який може не лише вирішувати конкуренцію ресурсів між кількома потоками, а й конкуренцію ресурсів між процесами.
Код тестування продуктивності
Запусти код
Результати тестів продуктивності
Примітка: Наведені вище дані є лише результатом апаратної продуктивності поточного тестового середовища і можуть бути порівняні лише між собою.
1) У різних тестах найшвидший спосіб не блокувати, тому намагайтеся уникати конкуренції за ресурси, що призводить до блокування роботи.
2) Interlocked.CompareExchange стабільно демонструє кращу продуктивність у багатопоточності, займаючи друге місце.
3) Третій замок, критична зона, також демонструє хорошу продуктивність, тому, будь ласка, спростуйте інших, хто каже, що ефективність замка низька.
4) Четверте місце — робота з атомною змінною (атомною), але наразі вона підтримує лише самозбільшення та відняття змінних, і застосовність не є сильною.
5) Продуктивність п'ятого блокування читання/запису (ReaderWriterLockSlim) теж нормальна, і він підтримує нічого, а практичність залишається досить хорошою.
6) Решта семафори, події та м'ютекс мають найгіршу продуктивність, звісно, мають власний обсяг застосування, але вони погано справляються з конкуренцією за ресурси.
Оригінальна адреса посилання:Вхід за гіперпосиланням видно.
|