Введение в разработку многопоточных приложений. Поморгаем int main() { while(true) { EnableLedOne(); DisableLedOne(); }

Презентация:



Advertisements
Похожие презентации
Многопоточное программирование Синхронизация потоков Лекция 11.
Advertisements

ПОТОКИ Начальные сведенияПОТОКИ Начальные сведения.
Многопоточное программирование ( часть 1) Лекция 10.
Модель приложений.NET. Среда платформы Win32, в которой выполняется программа, называется ее процессом. Эта среда состоит из: адресного пространства,
Параллелизм и потоки в Java For students of university Author: Oxana Dudnik.
Многопоточные приложения в Java Лекция 8. Многопоточность Многопоточность операционной системы – возможность одновременного выполнения более чем одной.
Многопоточное программирование на Java Java Advanced.
МНОГОПОТОЧНОЕ ПРОГРАММИРОВАНИЕ В JAVA Пакеты java.lang java.util.concurrent.
Многопоточное программирование. Виды параллелизма. Общая память Распределенная память.
Язык программирования C# Дмитрий Сошников
Параллельное программирование с использованием технологии OpenMP Аксёнов Сергей Владимирович к.т.н., доцент каф.ОСУ ТПУ Томский политехнический университет.
Многопоточное программирование на Java Java Advanced.
Исключительные ситуации. Схема обработки исключений Try { //охраняемый блок trow (new MyException();) } catch(MyExeption e) { … } catch(Exeption e){ …
Saint Petersburg, 2011 Java Lecture #06 Exceptions.
Программирование многоядерных архитектур (слайды для лекции 2013/04/20) Киреев С.Е., Маркова В.П., Остапкевич М.Б., Перепелкин В.А. МО ВВС ИВМиМГ СО РАН.
Синтаксис языка Java. Символы и синтаксис Перевод строчки эквивалентен пробелу Регистр в именах различается.
Введение в многопоточное программирование Java Advanced
Перегрузка операторов x = a + b результат 1-й операнд2-й операнд оператор По количеству операндов операторы делятся на: унарные (один операнд) бинарные.
Время жизни объектов Лекция 12. При запуске exe файла Windows анализирует заголовок exe файла для определения разрядности адресного пространства 32 или.
ДЕЛЕГАТЫ Лекция 7 1. Зачем нужны делегаты 2 И данные, и код располагаются в памяти компьютера по определенным адресам. Передача адресов данных в C# происходит.
Транксрипт:

Введение в разработку многопоточных приложений

Поморгаем int main() { while(true) { EnableLedOne(); DisableLedOne(); }

Поморгаем int Delay(int ms) { for(int i = 0; i < ms * k ; i++){} } int main() { while(true) { EnableLedOne(); Delay(300); DisableLedOne(); Delay(900); }

Одна лампочка t(мс)

Две лампочки t(мс)

Две лампочки t(мс) мс

Очередь заданий Task1, через 50мс Task2, через 100мс Task1, сейчас Task2, через 50мс Task2, сейчас t(мс)

Поморгаем с планировщиком void EnableLedOneTask() { EnableLedOne(); RegisterDelayedTask(DisableLedOneTask, 300); } void DisableLedOneTask() { DisableLedOne(); RegisterDelayedTask(EnableLedOneTask, 900); } int main() { RegisterDelayedTask(EnableLedOneTask, 0); RegisterDelayedTask(EnableLedTwoTask, 0); while(true) { Delay(50); ExecuteTaskByTime(); }

Sleep void LedOne () { while(true) { EnableLedOne(); Sleep(300); DisableLedOne(); Sleep(600); }

Sleep void LedOneThread() { B202 while(true) B203 { B204 EnableLedOne(); B205 Sleep(300); B207 DisableLedOne(); B208 Sleep(600); B209 } }

Sleep void LedOneThread() { int i = GetOnTime(); int j = GetOffTime(); while(true) { EnableLedOne(); Sleep(i); DisableLedOne(); Sleep(j); }

Стек и регистры j Регистры Стек i

Стек и регистры j Регистры Стек g h

Стеки и регистры Регистры i j Стек потока 1 i

Стеки и регистры Регистры Стек потока 2 g h j Стек потока 1 i g

Поток Физически – процедура потока, служебные данные и стек Логически – виртуальный процессор

Типы многопоточности Sleep() Поток 1Поток 2 t t

Типы многопоточности Кванты Sleep() Поток 1Поток 2 t t Квант кончился

Создание потоков WinAPI: CreateThread/TerminateThread.NET: class Thread static void Main(string[] args) { Thread thread = new Thread(DoA); thread.Start(); } static void DoA() { … }

Пул потоков WinAPI: QueueUserWorkItem.NET: class ThreadPool static void Main(string[] args) { ThreadPool.QueueUserWorkItem(DoA); } static void DoA(object state) { }

GUI void OnClick() { ThreadPool.QueueUserWorkItem(DoA); } void DoA(object state) { resultTextBox.Text = ComputeSmth(); }

GUI Очередь сообщений Поток окна Перерисуй окно Кликнули мышкой

GUI Очередь сообщений Поток окна Перерисуй окно Кликнули мышкой Обработай окончание вычисления

GUI static void DoA(object state) { _result = ComputeSmth(); resultTextBox.BeginInvoke(SetResult); } static void SetResult (object state) { resultTextBox.Text = _result; }

Проблемы многопоточности Проблемы корректности Проблемы живучести

Состояние гонки _i++; MOV EAX, [_ i ] INC EAX MOV [ _i ], EAX

«Одновременное» выполнение Поток 1 MOV EAX, [ i ] INC EAX MOV [ i ], EAX Поток 2 MOV EAX, [ i ] INC EAX MOV [ i ], EAX t

Многопроцессорная машина Процессор 1Процессор 2 Память Кэш 1Кэш 2 i = 2 i = 3

Многопроцессорная машина Процессор 1Процессор 2 Память Кэш 1Кэш 2 i = 2 i = 3 Когерентность кэша

Последовательное выполнение Поток 1 Enter() MOV EAX, [ i ] INC EAX MOV [ i ], EAX Exit() Поток 2 Enter() INC EAX MOV EAX, [ i ] MOV [ i ], EAX t

Критический регион … EnterCriticalRegion() _i++; LeaveCriticalRegion() …

Критический регион int taken = 0; void EnterCriticalRegion() { while(taken != 0) {} taken = 1; } void LeaveCriticalRegion() { taken = 0; }

Строгое чередование const int N = 2; int turn = 0; void EnterCriticalRegion (int i) { while (turn != i ) {} } void LeaveCriticalRegion (int i) { turn = (i + 1) % N; }

Алгоритм Петерсона(1981) bool flags[2]; int turn = 0; void EnterCriticalRegion (int i) { flags [ i ] = true ; turn = 1 - i ; while ( flags[1 - i] && turn != i ) {} } void LeaveCriticalRegion (int i) { flags [i] = false; }

CAS long CompareExchange(long *Destination, long Exchange, long Comparand); int taken = 0; void EnterCriticalRegion() { while( CompareExchange((&taken,1, 0)) {} } void LeaveCriticalRegion() { taken = 0; }

Interlocked Interlocked.Increment(ref _i);

Mutex static Mutex _mutex = new Mutex(); static void DoA(object state) { _mutex.WaitOne(); _i++; _mutex.ReleaseMutex(); }

Monitor void EnterCriticalRegion() { for(int i = 0; i < 1000 && ! CompareExchange((&taken,1, 0)) ; i++) {} if(taken == 0) { _mutex.WaitOne(); }

Monitor private static object _lockObject; static void DoA(object state) { lock(_lockObject) { ThreadUnsafeOperation(); } WinAPI: EnterCriticalSection/LeaveCriticalSection

Неблокирующая синхронизация

Фокус flags[i] = true; turn = 1 - i; while (flags[1 - i] && turn != i) { }

Фокус flags[i] = true; turn = 1 - i; int tmp1 = flags[1 - i] int tmp2 = turn != I …

Фокус flags[i] = true; int tmp1 = flags[1 - i] …

Фокус CPU1 flags[0] = true; int tmp1 = flags[1] … CPU2 flags[1] = true; int tmp1 = flags[0] …

Фокус CPU1 flags[0] = true; int tmp1 = flags[1] … CPU2 flags[1] = true; int tmp1 = flags[0] …

Многопроцессорная машина Процессор 1Процессор 2 Память Кэш 1Кэш 2 flags[0] = true flags[1] = true flags[0]=0 flags[1]=0 flags[0]=0 flags[1]=0

Фокус int tmp1 = flags[1 - i] flags[i] = true; …

Memory barrier flags[i] = true; Thread.MemoryBarrier(); int tmp1 = flags[1 - i] …

lock flags[i] = true; turn = 1 - i; lock (_object) { while (flags[1 - i] && turn != i) { }

Deadlock public static void Transfer(BankAccount a, BankAccount b, decimal amount) { lock (a) { if (a.m_balance < amount) throw new Exception("Insufficient funds."); lock (b) { a.m_balance -= amount; b.m_balance += amount; }

Deadlock Поток 1Поток 2 Lock(счет1)Lock(счет2) Lock(счет1) t

Банковский алгоритм public static void Transfer(BankAccount a, BankAccount b, decimal amount) { LockManager.LockAccounts(a, b) if (a.m_balance < amount) throw new Exception("Insufficient funds."); a.m_balance -= amount; b.m_balance += amount; }

Сортировка Поток 1Поток 2 Lock(счет1) Lock(счет2) Lock(счет1) Lock(счет2) t

Что почитать Concurrent Programming on Windows (Joe Duffy) CLR via C# (Jeffrey Richter ) Memory Barriers: a Hardware View for Software Hackers