Upload
eleks-developers-courses-if
View
1.689
Download
5
Embed Size (px)
Citation preview
Concurrency
Типові приклади використанняResponsiveness
Багатозадачність ОС
Виконання операцій поза UI (I/O)
Performance
Обробка даних паралельно (CPU)
Виконання кількох задач паралельно(CPU-CPU, CPU-I/O, I/O-I/O)
ProcessПроцес визначає virtual address space
Досягається ізоляція, оскільки
- процеси не можуть напряму адресувати пам’ять інших процесів
Також можливе спільне використання:
- спільна бібліотека може входити до адресного простору кількох процесів
Процес не виконує код,
а лише надає ресурси і контекст для виконання потоків
Потоки (threads) виконують код
Потоки виконуються в межах процесу
Мають доступ до всього адресного простору процесу.
Кожен потік має свій стек викликів (локальні змінні), вказівник поточної інструкції та значення регістрів CPU
Виконання потоків у Windows- Багатозадачна ОС
- Витісняюче планування на основі пріоритетів
- (preemptive scheduling, priority-based)
- CPU завжди виконує той потік, який має найвищий пріоритет (і який готовий до виконання)
Планування (scheduling) Windows- Потік виконується протягом фіксованого інтервалу
часу (time slice)
- По закінченню інтервалу ОС перевіряє, чи є готовий потік з таким же пріоритетом
- Якщо є, потік витісняється
- Як тільки з’являється потік з вищим пріоритетом, потік витісняється
- Навіть якщо його інтервал не закінчився
Переключення контексту
(context switching)Вибравши новий потік для виконання, ОС переключає контекст:
Зберігається стан регістрів CPU + IP попереднього потоку
Відновлюються регістри CPU нового потоку
Потік звільняє CPU, коли:- Завершився time slice
- Переходить в стан очікування самостійно
- Диск, мережа, пам’ять (!), синхронізація
- Витісняється потоком з вищим пріоритетом
- Який закінчив щось очікувати (диск, мережа,...)
- Пріоритет якого збільшився
- Потік завершується
- …
Windows та Linux планують потоки, не процеси
Наслідок:
Процес А має 1 потік
Процес Б має 9 потоків
Процес Б отримає 90% процесорного часу
(за умови однакового пріоритету потоків)
UI message loop- Один GUI потік обробляє повідомлення з черги:
- Clicks, repaints, mouse moves, key presses, …
- Події обробляються послідовно
- Отже, якщо одна подія займає довгий час, решта будуть чекати
- Отже, довготривалі події ніколи не повинні виконуватись в UI потоці
- I/O, важкі обчислення (див. наст. слайд)
Довготривалі події ніколине повинні виконуватись в UI потоці- UI потік не повинен блокуватись чекаючи
завершення цих операцій
- В т.ч. коли ці операції виконуються іншим потоком
- Для повернення результатів – signals and slots
- “Qt developers are used to working with this kind of asynchronous behavior”http://qt-project.org/doc/qt-5.0/qtcore/thread-basics.html
Thread pool- Створювати і видаляти потоки дорого
- Пул потоків виконує завдання використовуючи створений наперед набір потоків
- Залежно від навантаження пул створює додаткові потоки або видаляє непотрібні
Типові задачі- Поділити дані на частини і обробляти
паралельно
- Виконувати декілька незалежних задач паралельно
- Виконати довготривалу операцію поза UI
Паралелізм даних
...
Thread 1
...
Thread 2
Паралельні незалежні задачі
Task 1
Task 2
Task 3
SeqSeq
Паралельні незалежні задачі
Seq
Future
Seq Seq
Seq
Future
Seq
Future
Seq
Future
Seq Seq
Паралельні незалежні задачі
Операції поза UI
Seq
DB Call
Event loop
Seq
Використання спільних данихauto count = 0;
100{
{count++;
});}
int temp = count;temp = temp + 1;count = temp;
Використання спільних даних
Потік A
int temp = count; // 0
temp = temp + 1; // 1
count = temp; // 1
count = 0
Потік B
int temp = count; // 0
temp = temp + 1; // 1
count = temp; // 1
count = 1 // WRONG! Should be 2
Доступ до спільних даних повинен бути синхронізованимauto count = 0;std::mutex mutex;
{
{std::lock_guard<std::mutex> lock(mutex);count++;
});}
mutex.lock();// ...mutex.unlock();
Qt has its own bicycle for this
Використання спільних даних
Потік Amutex.lock();int temp = count; // 0
temp = temp + 1; // 1count = temp; // 1mutex.unlock();
count = 0
Потік B
mutex.lock();
int temp = count; // 0temp = temp + 1; // 1count = temp; // 1mutex.unlock();
Синхронізацією керувати складноБагато нюансів, про які ми навіть не здогадуємось (як з count++)Second order ignorance http://c2.com/cgi/wiki?OrdersOfIgnorance
Використовуйте готові засоби: алгоритми, конкурентні колекції, tasks, futures, QtConcurrent, QThreadPool, signals and slots
Advanced Qt
• Thread-safety and reentrance
• Working with threads
• Basic synchronization techniques
• High-level concurrency API
Working with threads
• QThread - a wrapper around OS thread
• do not subclass QThread
• push processing objects to QThread instance
• do not allocate heap memory in processing object constructor
• be sure that thread is shut down when deleting QThread
• be careful while connecting signals/slots in multithreading applications
Basic synchronization techniques
• QMutex and QMutexLocker
• QReadWriteLock