Проблеми синхронізації
З оглядуна, що всі потоки в домені додатку мають
паралельний доступ до даних, що розділяються
додатка, уявіть, що може статися, якщо кілька потоків
одночасно звернуться до одного і того ж елементу
даних.
Оскільки планувальник потоків випадковим чином
буде припиняти їхню роботу, що якщо перший потік
буде перерваний до того, як завершить свою роботу? -
другий потік після цього прочитає нестабільні дані.
Andrey Gladky
KspDevelop@gmail.com 3
4.
Синхронізація з використаннямключового слова “lock”
Це ключове слово дозволяє визначати контекст операторів, які
повинні бути синхронізованими між потоками.
В результаті вхідні потоки не можуть перервати поточний потік,
заважаючи йому завершити свою роботу.
Ключове слово lock вимагає вказівки маркера (посилання на
об'єкт), який повинен бути отриманий потоком для входу в
контекст блокування.
// Використовувати поточний об'єкт як маркер потоку
lock(this)
{
// Весь код всередині цього контексту є безпечним до
потокам.
}
Однак якщо ви блокуєте область коду всередині відкритого метод, безпечніше (і
взагалі краще) оголосити закриту змінну object для використання в якості маркера
блокування:
Andrey Gladky
KspDevelop@gmail.com 4
Синхронізація з використаннямтипу
System.Threading.Monitor
Оператор lock мови C# - це насправді скорочена
нотація для роботи з класом System.Threading.Monitor.
При обробці компілятором C# контекст lock
перетворюється в наступну конструкцію:
Monitor.Enter(threadLock);
try
{
//Do something
}
finally
{
Monitor.Exit(threadLock);
}
Andrey Gladky
KspDevelop@gmail.com 6
Синхронізація з використаннямтипу interlocked
Не заглядаючи в CIL-код, дуже важко повірити, що
присвоювання і прості арифметичні операції не є
атомарними. З цієї причини в просторі імен
System.Threading існує тип, що дозволяє оперувати
одиночним елементом даних атомарно і з меншими
накладними витратами, ніж тип Monitor.
Andrey Gladky
KspDevelop@gmail.com 8
Метод Опис
CompareExchange () Безпечно перевіряє два значення на рівність і, якщо
вони рівні, замінює одне зі значень
Decrement() Безпечно зменшує значення на 1
Exchange() Безпечно змінює два значення місцями
Increment() Безпечно зменшує значення на 1
Mutex
Клас Mutex (mutualexclusion - взаємне виключення або
м'ютекс) є одним з класів в .NET Framework, що
дозволя’ забезпечити синхронізацію серед безлічі
процесів. Він дуже схожий на клас Monitor тим, що
теж допускає наявність лише одного власника. Тільки
один потік може отримати блокування і мати доступ до
захищених м'ютексами синхронізованим областям
коду.
Andrey Gladky
KspDevelop@gmail.com 10
Semaphore
Семафор подібний м'ютексові,за винятком того, що
він надає одночасний доступ до загального ресурсу не
одному, а кільком потокам. Тому семафор придатний
для синхронізації цілого ряду ресурсів.
Семафор управляє доступом до загального ресурсу,
використовуючи для цієї мети лічильник. Якщо
значення лічильника більше нуля, то доступ до ресурсу
дозволений. А якщо це значення дорівнює нулю, то
доступ до ресурсу заборонений.
За допомогою лічильника ведеться підрахунок
кількості дозволів. Отже, для доступу до ресурсу потік
повинен отримати дозвіл від семафора.
Andrey Gladky
KspDevelop@gmail.com 12
Синхронізація з використанняматрибута
[Synchronization]
Цей атрибут рівня класу ефективно блокує весь код
екземпляра об'єкта, забезпечуючи безпеку щодо потоків.
Коли середовище CLR розміщує об'єкти, забезпечені
атрибутами [Synchronization], вона поміщає об'єкт в
контекст синхронізації.
Об'єкти, які не повинні виходити за межі контексту,
повинні успадковуватися від класу ContextBoundObject.
Andrey Gladky
KspDevelop@gmail.com 14
Ключові слова asyncі await
Ключове слово async мови C# застосовується для
вказівки на те, що метод, лямбда-вираз або анонімний
метод повинні викликатися в асинхронному режимі
автоматично.
Асинхронні методи використовуються для
неблокуючих операцій. Вираз await в асинхронному
методі не блокує поточний потік на час виконання
очікуваного завдання. Замість цього вираз реєструє
решту методу як продовження і повертає управління
викликаючому об'єкту асинхронного методу.
Andrey Gladky
KspDevelop@gmail.com 16
Ключові слова asyncі await
Синхронний метод повертає управління, коли його
робота завершується (крок 5), тоді як асинхронний
метод повертає значення завдання, коли його робота
припиняється (кроки 3 і 6). Коли асинхронний метод в
кінцевому рахунку завершує роботу, завдання
позначається як завершена і результат, при його
наявності, зберігається в завданні.
Ключові слова async і await не створення додаткових
потоків. Асинхронні методи не вимагають
багатопоточності, оскільки асинхронний метод не
виконується у власному потоці. Метод виконується в
поточному контексті синхронізації і використовує час
в потоці, тільки коли метод активний.
Andrey Gladky
KspDevelop@gmail.com 19
20.
Ключові слова asyncі await
Якщо за допомогою модифікатора async вказати, що
метод є асинхронним, з'являться такі дві можливості.
Асинхронний метод зможе використовувати ключове слова
await для позначення точок призупинення. Оператор await
повідомляє компілятору, що асинхронний метод не може
виконуватися після цієї точки до завершення очікуваного
асинхронного процесу. На цей час управління повертається
викликаючому об'єкту асинхронного методу.
Призупинення асинхронного методу на вираженні await не є
виходом з методу і блок finally не виконуються.
Метод, зазначений ключовим словом async, сам може бути
очікуваним методом.
Andrey Gladky
KspDevelop@gmail.com 20