2. Use cases
- Масштабованість на multi-CPU машинах
- Виконання швидше
- Обробка більшої кількості запитів
- Приховування затримок (hiding latency)
- Обчислення, доки чекаємо на IO
- Відгук UI (responsiveness)
- «Усунення» блокуючих операцій
4. Process
Процес визначає virtual address space.
Досягається ізоляція, оскільки
- процеси не можуть напряму адресувати
пам’ять інших процесів.
Разом з тим, спільне використання:
- спільна бібліотека може входити до
адресного простору кількох процесів.
5. Процес не виконує код,
а лише надає ресурси і контекст для
виконання потоків
6. Потоки (threads) виконують код
Потоки виконуються в межах процесу
Мають доступ до всього адресного простору
процесу.
Кожен потік має свій стек та значення
регістрів CPU
7. Windows
- Багатозадачна ОС
- Витісняюче планування на основі пріоритетів
- (preemptive scheduling, priority-based)
- Потік виконується на будь-якому CPU
- CPU завжди виконує той потік, який має
найвищий пріоритет (і який готовий до
виконання)
8. Планування (scheduling)
- Потік виконується протягом сталого періоду часу
– кванту
- Величина квантів може бути різна, залежить від:
- Конфіга системи (короткі, довгі)
- Статуса процесу (активний, фоновий)
- По закінченню кванта ОС перевіряє, чи є готовий
потік з таким же пріоритетом
- Як тільки з’являється потік з вищим пріоритетом,
поточний потік витісняється
- Навіть якщо його квант не закінчився
10. Потік звільняє CPU, коли:
- Переходить в стан очікування самостійно
- Диск, мережа, пам’ять (!), синхронізація
- Витісняється потоком з вищим пріоритетом
- Який закінчив щось очікувати (диск, мережа,...)
- Його пріоритет збільшився
- Завершився квант
- Завершився потік
11. Динамічне підвищення
пріоритету
- Після закінчення вводу/виводу
- Після закінчення очікування
- При пробудженні GUI потоків через
операції з вікнами
- Готовий до виконання потік довший час не
має шансу виконатись
Також при цьому може збільшуватись квант.
12. Вибір CPU для потоку
- Вибирається процесор, який простоює
- Якщо немає вільного процесора –
витіснення на ідеальному процесорі
13. Scheduling granularity
Windows планує потоки, не процеси
Наслідок:
Процес А має 1 потік
Процес Б має 9 потоків
Процес Б отримає 90% процесорного часу
(за умови однакового пріоритету потоків)
14. Threads in .NET
- Створення потоку:
- new Thread(Action)
- Запуск:
- Thread.Start()
- Очікування доки потік завершиться:
- Thread.Join()
15. Thread pool
- Пул потоків виконує завдання
використовуючи вже створений набір
потоків
- Додання нового завдання:
- ThreadPool.QueueUserWorkItem(delegate)
16. UI message loop
- Один GUI потік обробляє повідомлення з черги:
- Clicks, repaints, mouse moves, key presses, …
- Події обробляються послідовно
- Отже, якщо одна подія займає довгий час, решта
будуть чекати
- Отже, довготривалі події ніколи не повинні
виконуватись в UI потоці
- IO, важкі обчислення
17. Оновлення контролів
- Щоб змінити контрол, код повинен
виконуватись в UI потоці
- Інші потоки можуть програмно додати
повідомлення в чергу UI потоку
19. Task Parallel Library (TPL)
Since .NET 4.0
http://msdn.microsoft.com/en-us/library/dd460717.aspx
MSDN Parallel Computing Dev Center
20. Task
http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx
Абстрагує значення, яке буде* доступне в
майбутньому.
Значення є результатом
- Обчислення (CPU)
- Вводу (IO)
Task є .NET реалізацією future and promise
21. Значення буде* доступне
- Можливо вже є доступне
- Таск завершився до звернення за результатом,
- Також таск міг виконатись в цьому ж потоці
- Можливо не буде, бо станеться помилка
- Або обчислення буде відмінено
22. Створення і запуск
Task Task.Factory.StartNew(Action);
Task<TResult> Task.Factory.StartNew(Func<TResult>);
Або Task constructor + Task.Start() method
23. Виконання
Task – не потік.
За замовчуванням таски виконуються
потоками з thread pool
Наслідок 1: таск може почати виконуватись не
одразу
Наслідок 2: довготривалий таск буде займати потік
з thread pool
(цей потік не зможе працювати над рештою задач)
30. Unhandled exceptions
Якщо не обробити exception, TPL його перевикине
при фіналізації Task’a
Викличеться подія
TaskScheduler.UnobservedTaskException
Помилка вважається обробленою при:
- Виклику Task.Result, Task.Wait() etc.
- Звертанні до Task.Exception
32. Continuations
Задача: після завершення таска виконати
наступний.
В наступному таску – доступний результат
попереднього.
Task<U> Task<T>.ContinueWith(antecedent => {...});
TaskFactory.ContinueWhenAll(Task[], tasks => {...});
35. Деякі приклади використання Tasks
- Досягнення паралелізму
- Виконання CPU-bound задач паралельно
- Виконання IO-bound задач паралельно
- Responsive UI
Demo
37. Data race
int count = 0;
for (int i = 0; i < data.Length; i++)
{
var task = Task.Factory.StartNew(() =>
{
count++; Not atomic!
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
38. Preemption
Thread A
reg = read count (1) Thread B
reg = read count (1)
inc reg (2)
write reg to count (2)
inc reg (2)
write reg to count (2)
39. Рішення 1 – interlocked
int count = 0;
for (int i = 0; i < data.Length; i++)
{
var task = Task.Factory.StartNew(() =>
{
Atomic,
Interlocked.Increment(ref count);
Flushes caches
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
40. Рішення 2 – locking (critical section)
int count = 0;
object syncRoot = new object();
for (int i = 0; i < data.Length; i++)
{
var task = Task.Factory.StartNew(() =>
{
lock (syncRoot) Other threads
{ cannot acquire
held lock
count++;
}
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
42. Parallel.For() and ForEach()
Заблокується, доки всі ітерації не виконаються
Parallel.For(0, data.Length, i =>
{ Є можливість зробити
Break, передавши state
ProcessItem(data, i);
});
Parallel.ForEach(data, value =>
{
ProcessItem(value);
});
43. Parallel LINQ (PLINQ)
var result =
from value in data.AsParallel()
where value % 2 == 0
let cube = Math.Pow(value, 3)
let processed = ProcessItem(value)
select new { Cube = cube, Result = processed };
parallelResult.ToArray();
Виконання почнеться тут
44. Варто також дізнатись про:
- Task.Status, Task lifecycle
http://blogs.msdn.com/b/pfxteam/archive/2009/08/30/9889070.aspx
- Continuations http://msdn.microsoft.com/en-us/library/dd235663
- TaskSchedulers http://msdn.microsoft.com/en-us/library/dd997402
- Cancellation http://msdn.microsoft.com/en-us/library/dd997364.aspx
- Synchronization primitives http://msdn.microsoft.com/en-
us/library/ms228964.aspx
- Concurrent collections http://msdn.microsoft.com/en-
us/library/system.collections.concurrent.aspx
- Безплатна книжка, ще одна