cpp-2013 #19 concurrency

Post on 03-Jul-2015

1.689 Views

Category:

Documents

5 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

top related