Реферат: Паралельноє програмирование
Дозволяє потоку чекати сигналу від іншого потоку.
так
середньо
Wait and Pulse
Дозволяє потоку чекати, поки не виконається задана умова блокування.
немає
середньо
Табл. 2.3 Сигнальні конструкції
Конструкція | Призначення | Доступна з інших процесів | Швидкість |
Interlocked |
Виконання простих не блокуючих атомарних операцій. |
Так – через пам'ять, що розділяється |
дуже швидко |
volatile |
Для безпечного не блокуючого доступу до полів. |
Так – через пам'ять, що розділяється |
дуже швидко |
Табл. 2.4 Не блокуючі конструкції синхронізації
Блокування
Коли потік зупинений в результаті використання конструкцій, перерахованих в наведених вище таблицях, говорять, що він блокований. Будучи блокованим, потік негайно перестає отримувати час CPU, встановлює властивість ThreadState в WaitSleepJoin і залишається в такому стані, поки не розблоковується. Розблокування може статися в наступних чотирьох випадках (кнопка виключення живлення не вважається!):
- виконається умова розблокування;
- витече|закінчуватиметься| таймаут операції (якщо він був заданий);
- по перериванню через Thread .Interrupt;
- по аварійному завершенню через Thread .Abort.
Потік не вважається блокованим, якщо його виконання припинене методом Suspend , що не рекомендується.
Виклик Thread .Sleep блокує поточний потік на вказаний час (або до переривання):
static| void| Main|()
{
Thread|.Sleep(0); |
Thread|.Sleep(1000);
Thread|.Sleep(TimeSpan|.FromHours(1));
Thread|.Sleep(Timeout|.Infinite);
}
Якщо бути точнішим, Thread .Sleep відпускає CPU і повідомляє, що потоку не повинен виділятися час у вказаний період. Thread .Sleep(0) відпускає CPU для виділення одного кванта часу наступному потоку в черзі на виконання.
Унікальність Thread .Sleep серед інших методів блокування в тому, що він припиняє прокачування повідомлень Windows в додатках WindowsForms або COM-окружении потоку в однопоточному апартаменті. Через це тривале блокування головного (UI) потоку додатка WindowsForms наводить до того що додаток перестає відгукуватися – і отже, використання Thread .Sleep потрібно уникати незалежно від того, чи дійсно прокачування черги повідомлень технічно припинене. У старому COM-среде ситуація складніша, там інколи може бути бажане блокування за допомогою Sleep з одночасним прокачуванням черги повідомлень.
Клас Thread також надає метод SpinWait , який не відмовляється від часу CPU, а навпаки, завантажує процесор в циклі на задану кількість ітерацій. 50 ітерацій еквівалентні паузі приблизно в мікросекунду, хоча це залежить від швидкості і завантаження CPU. Технічно SpinWait – не блокуючий метод: ThreadState такого потоку не встановлюється в WaitSleepJoin , і потік не може бути перерваний з іншого потоку. SpinWait рідко використовується – його головне вживання це чекання ресурсу, який повинен звільниться дуже скоро (у перебігу мікросекунд) без виклику Sleep і витрати процесорного часу на перемикання потоку. Проте ця методика вигідна лише на багатопроцесорних комп'ютерах, на однопроцесорному комп'ютері в ресурсу немає жодного шансу звільнитися, поки чекаючий на SpinWait потік не розтратить залишок кванта часу, а значить, необхідний результат недосяжний спочатку. А часті або тривалі виклики SpinWait даремно розтрачує час CPU.
Чекання|очікування| завершення