system programing module 2

22
System programing Module 2 Thread

Upload: andriy-gladkiy

Post on 14-Apr-2017

82 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: System programing module 2

System programingModule 2 Thread

Page 2: System programing module 2

2

ПотікУ кожному процесі Windows міститься початковий "потік", який функціонує в якості вхідної точки для програми.

Потік - це шлях виконання всередині процесу.

Перший потік, створений точкою входу процесу, називається главньш потоком.

У будь-якій виконуваній програмі .NET, точка входу позначається за допомогою методу Main(). При виклику цього методу головний потік створюється автоматично.

Andrey Gladky [email protected]

Page 3: System programing module 2

3

ПотікВ рамках платформи .NET не існує прямого відповідношення "один до одного" між доменами додатків (AppDomain) і потоками. Фактично певний домен програми може мати кілька потоків, що виконуються в кожен конкретний момент часу.

Більш того, конкретний потік не прив'язаний до одного домену додатка протягом свого часу життя. Потоки можуть перетинати границі доменів додатків, коли це вважатимуть за доцільне планувальник потоківWindows і CLR-середовище .NET.

Andrey Gladky [email protected]

Page 4: System programing module 2

4

ПотікНезважаючи на те що активні потоки можуть переміщатися між границями доменів додатків, кожен потік в будь-який конкретний момент часу може виконуватися тільки всередині одного домена додатку.

Щоб програмно отримати доступ до домену додатка, в якому розміщений поточний потік, використувується статичний метод Thread.GetDomain():

static void ExtractAppDomainHostingThread (){ // Отримати домен програми, що розміщує поточний потік. AppDomain ad = Thread.GetDomain();}

Andrey Gladky [email protected]

Page 5: System programing module 2

5

ПотікОдин з багатьох болючих аспектів многопоточного програмування пов'язаний з обмеженим контролем над використанням потоків операційною системою або CLR-середовищем.

Наприклад, написавши блок коду, який створює новий потік виконання, не можна гарантувати, що цей потік запуститься негайно. Замість цього такий код лише просить операційну систему запустити потік, як тільки це буде можливо (зазвичай, коли планувальник потоків добереться до нього).

Andrey Gladky [email protected]

Page 6: System programing module 2

6

ПотікБільш того, враховуючи, що потоки можуть переміщатися між границями додатків і контекстів, коли це потрібно CLR, ви повинні уявляти, які аспекти програми є змінюванні в потоках (наприклад, піддаються багатопотокового доступу), а які операції - атомарними (змінюванні в потоках операції небезпечні ).

Якщо вихідний потік ще не повністю завершив свою операцію, другий вхідний потік може побачити об'єкт в частково зміненому стані. У цей момент другий потік, по суті, читає фіктивні дані, що безумовно може призвести до дуже дивних помилок, знайти і налагодити які навіть ще важче.

Andrey Gladky [email protected]

Page 7: System programing module 2

7

Багатопоточні додаткиХоча платформа .NET не може повністю приховати складності, пов'язані з побудовою надійних багатопоточних додатків, цей процес все ж значно спрощений.

Використовуючи типи, визначені всередині простору імен System.Threading, бібліотеку Task Parallel Library (TPL) в .NET 4.0 і вище, а також ключові слова asinc і await мови C# в .NET 4.5, можна працювати з безліччю потоків, прикладаючи мінімальні зусилля.

Andrey Gladky [email protected]

Page 8: System programing module 2

8

namespase System.Threading

Andrey Gladky [email protected]

Тип ПризначенняInterlocked Цей тип надає атомарні операції для змінних, розділених між

декількома потокамиMonitor Цей тип забезпечує синхронізацію потокових об'єктів,

використовуючи блокування і очікування/сигнали. Ключове слово lock мови C # застосовує "за лаштунками" об'єкт Monitor

Mutex Цей примітив синхронізації може використовуватися для синхронізації між границями доменів додатків

ParameterizedThreadStart

Цей делегат дозволяє потоку викликати методи, які приймають довільну кількість аргументів

Semaphore Цей тип дозволяє обмежити кількість потоків, які можуть мати доступ до ресурсу або до певного типу ресурсів одночасно

Thread Цей тип являє потік, що виконується в CLR-середовищі. Використовуючи етоттіп, можна порождатьдополнітельние потоки в вихідному домені додатку

ThreadPool Цей тип дозволяє взаємодіяти з підтримуваним CLR пулом потоків всередині заданого процесу

Page 9: System programing module 2

9

namespase System.Threading

Andrey Gladky [email protected]

Тип ПризначенняThreadPriority Це перерахування представляє рівень пріоритету потоку

(Highest, Normal і т.д.)ThreadStart Цей делегат дозволяє вказати метод для виклику в заданому

потоці. На відміну отделегата ParametrizedThreadStart, цільові методи ThreadStart завжди повинні мати один і той же прототип

ThreadState Це перерахування задає допустимі стану потоку (Running, Aborted і т.д.)

Timer Цей тип надає механізм виконання методу через зазначені інтервали часу

TimerCallback Цей тип делегата використовується в поєднанні з типами Timer

Page 10: System programing module 2

10

Статичні члени класу Thread

Andrey Gladky [email protected]

Тип ПризначенняCurrentContext Ця властивість, призначена тільки для читання, повертає

контекст, в якому в даний момент виконується потікCurrentThread Це властивість, призначена тільки для читання, повертає

посилання на поточний виконуванийя потікGetDomain()GetDomainID()

Цей метод повертає посилання на поточний домен додатка або ідентифікатор домену, в якому виконується поточний потік

Sleep() Цей метод призупиняє поточний потік на зазначений час

Page 11: System programing module 2

11

Члени рівня екземпляра класу Thread

Andrey Gladky [email protected]

Тип ПризначенняIsAlive Повертає буливське значення, яке вказує на те, чи

запущений потік (і поки ще не перерваний і не скасований)IsBackground Отримує або встановлює значення, яке вказує, чи є даний

потік фоновимName Дозволяє встановити дружнє текстове ім'я потоку

Priority Отримує або встановлює пріоритет потоку, який може приймати значення з перерахування ThreadPriority

ThreadState Отримує стан даного потоку, яке може приймати значення з перерахування ThreadState

Page 12: System programing module 2

12

Члени рівня екземпляра класу Thread

Andrey Gladky [email protected]

Тип ПризначенняAbort() Вказує CLR-середовищу на необхідність припинення

потоку, як тільки це буде можливоInterrupt() Перериває (призупиняє) поточний потік на відповідний

період очікуванняJoin() Блокує викликаючий потік до тих пір, поки вказаний потік

(той, на якому викликаний метод Join ()) не завершитьсяResume() Відновлює раніше призупинений потік

Start() Вказує CLR-середовищу на необхідність запуску потоку, як тільки це буде можливо

Suspend() Призупиняє потік. Якщо потік вже припинений, виклик Suspend () не дає ніякого ефекту

Page 13: System programing module 2

13Andrey Gladky [email protected]

Демонстрація

Page 14: System programing module 2

14

Ручне створення вторинних потоківКроки для ручного створення потоку:

1. Створіть метод, який буде служити точкою входу для нового потоку.

2. Створіть новий екземпляр делегата ParametrizedThreadStart (або ThreadStart), передавши конструктору адресу методу, який був визначений на кроці 1.

3. Створіть об'єкт Thread, передавши конструктору як аргумент делегат ParametrizedThreadStart/ThreadStart.

4. Встановіть початкові характеристики потоку (ім'я, пріоритет і т.д.).

5. Викличте метод Thread.Start(). Це призведе до запуску CLR-середовищем потоку для методу, на який посилається делегат, створений на кроці 2, при першій же можливості.

Andrey Gladky [email protected]

Page 15: System programing module 2

15

Асинхронний виклик методів

Andrey Gladky [email protected]

Page 16: System programing module 2

16

Роль делегатів .NETДелегат .NET - це по суті безпечний щодо типів, об'єктно-орієнтований покажчик на функцію.

З типу делегата, .NET компілятор C# побудує запечатаний клас, наслідуваного від System.MulticastDelegate.

Ці базові класи надають кожному делегату можливість підтримувати список адресів методів, які можуть бути викликані в більш пізній час.

public sealed class BinaryOperation : System.MulticastDelegate{ public BinaryOperation(object target, uint functionAddress); public int Invoke(int x, int у) ; public IAsyncResult BeginInvoke(intx, int y, AsyncCallback cb, object state); public int EndInvoke(IAsyncResult result);}

Andrey Gladky [email protected]

Page 17: System programing module 2

17

Асинхронна природа делегатівКоли компілятор C# обробляє ключове слово delegate, він динамічно генерує клас, який визначає два методи з іменами BeginInvoke() і EndInvoke().

public sealed class BinaryOperation : System.MulticastDelegate{ // Використовується для асинхронного виклику методу public IAsyncResult BeginInvoke(int x, int у, AsyncCallback cb, object state); // Використовується для отримання значення, що повертається // викликаним методом. public int EndInvoke(IAsyncResult result);}

Andrey Gladky [email protected]

Page 18: System programing module 2

18

Інтерфейс IAsyncResultМетод BeginInvoke() завжди повертає об'єкт, який реалізує інтерфейс IAsyncResult, в той час як EndInvoke() вимагає єдиний параметр сумісного з IAsyncResult типу.

Сумісний з IAsyncResult об'єкт, що повертається з BeginInvoke() - це в основному зв'язуючий механізм, який дозволяє викликаючому потоку отримати результат виклику асинхронного методу через EndInvoke() в більш пізній час.

public interface IAsyncResult{ object AsyncState { get; } WaitHandle AsyncWaitHandle { get; } bool CompletedSynchronously { get; } bool IsCompleted { get; }}

Метод, який повертає void, можна просто викликати асинхронно і забути.

Andrey Gladky [email protected]

Page 19: System programing module 2

19

Синхронізація викликаючого потоку

Щоб дозволити викликаючому потоку з'ясовувати, чи завершив свою роботу асинхронно викликаний метод, в інтерфейсі IAsyncResult передбачено властивість IsCompleted. З її допомогою викликаючий потік може визначати, чи дійсно асинхронний виклик був завершений, перш ніж звертатися до EndInvoke(). Якщо метод ще не завершився, властивість IsCompleted повертає false,

Andrey Gladky [email protected]

Page 20: System programing module 2

20

Роль делегата AsyncCallbackЗамість опитування делегата з метою визначення, чи завершився асинхронно викликаний метод, було б більш ефективно змусити вторинний потік інформувати викликаючий потік про завершення виконання завдання.

Щоб включити таку поведінку, знадобиться передати методу BeginInvoke() екземпляр делегата System.AsyncCallback.

Коли передаєтся об'ект AsyncCallback, делегат буде автоматично викликати вказаний метод по завершенні асинхронного виклику.

Метод зворотного виклику буде викликаний у вторинному потоці, а не в первинному.Andrey Gladky

[email protected]

Page 21: System programing module 2

21

Передача і отримання спеціальних даних стану

Фінальним аспектом асинхронних делегатів, який повинен бути врахований, є останній аргумент методу BeginInvoke(). Цей параметр дозволяє передавати додаткову інформацію про стан методу зворотного виклику з первинного потоку.

Для отримання цих даних в контексті методу зворотного виклику використовується властивість AsyncState вхідного параметра IAsyncResult.

Andrey Gladky [email protected]

Page 22: System programing module 2

22Andrey Gladky [email protected]

Демонстрація