Общество Мертвых Потоков

123
Общество Мертвых Потоков Алексей Федоров, Одноклассники / JUG.ru

Upload: alexey-fyodorov

Post on 15-Jan-2017

1.566 views

Category:

Engineering


0 download

TRANSCRIPT

Общество  Мертвых  Потоков

Алексей  Федоров,  Одноклассники  / JUG.ru

Зачем  вы  здесь?

3

Чего  не  будет  в  презентации

• Определений  из  учебника- Больше  интересует  сама  концепция

• Сравнения  производительности• Советов,  как  правильно  писать  код• Холиваров*• Серебряных  пуль,  волшебных  фреймворков и  т.п.

*  Нет,  ну  если  кто-­‐то   очень  захочет,  то  можно,   конечно…

4

А  что  будет-­то?

• Пара  простых  многопоточных  примеров• Куча  связанных  с  ними  проблем• Варианты  решений- Которые,  разумеется,  не  работают

- Ну  некоторые  работают- Иногда

- Наверное…

5

Пререквизиты

Нужно  примерно понимать,  что  такое• Thread• Runnable• synchonized• Lock lock = new ReentrantLock(false)• volatile• AtomicInteger• Compare-And-Set

6

Стенд

• Apple  MacBook  Pro  Retina,  2014- Intel  Core  i7- 4  cores  x  2  threads  =  8  HW  threads- 2,3  GHz

- 16  Gb  RAM- Oracle  JDK  8  update  60

• Mac  OS  X  10.10.5

Проблема  обедающих  философов

Dijkstra,  1965Hoare,  1985

Что  это?

8

• 5  философов  по  кругу– Тарелка  с  едой  перед  каждым– Вилки  между  тарелками

• Каждый  может– Размышлять– Брать  соседнюю  вилку– Есть  (строго  двумя  вилками!)– Класть  одну  вилку

Задача  о  философах

9

Проблемы  с  обедающими  философами

Пусть  каждый  философ  действует  по  некоторому  алгоритму

• Могут  ли  все  философы  умереть  с  голоду?

• Можно  ли  составить  такой  алгоритм,  чтобы  все  философы  гарантированно не  умерли  с  голоду?

10

Параметры  задачи

• Количество  философов• Есть  ли  возможность  положить  вилку,  не  пожрамши• Сколько  времени  философ  ест- Фиксированное  или  случайная  величина

• Сколько  времени  философ  размышляет- Фиксированное  или  случайная  величина- Как  это  время  соотносится  с  временем  еды

• Какие  ещё  инструменты/элементы  есть  в  системе?• Что  ещё?

11

Фиксированное  время  и  случайное  время

• Случайное  время  задаётся  какой-­‐то  функцией  распределения

• Константа  тоже задаётся  функцией  распределения- (А  бывают  ли  вообще  константы  в  реальном  мире?)

12

Фиксированное  время  и  случайное  время

• Случайное  время  задаётся  какой-­‐то  функцией  распределения

• Константа  тоже задаётся  функцией  распределения- (А  бывают  ли  вообще  константы  в  реальном  мире?)

Решение

14

Пронумеруем  философов  и  вилки

1

2 3

4

51

2

3

4

5

Demo  1.  Сено-­‐солома

16

Простое  решение

• Когда  философ  хочет  есть,  он  делает  следующие  шаги:1. Берёт  левую  от  себя  вилку  («сено»)2. Берёт  правую  от  себя  вилку  («солома»)3. Ест4. Кладёт  одну  вилку5. Кладёт  другую  вилку6. Размышляет

• И  так  по  кругу

17

Моделирование  на  Java

18

Deadlock

19

Теория

21

Ресурсы  и  взаимоблокировка

Ресурс – объект,  к  которому  предоставляется  доступ

Во  время  работы  процесс  может  брать  (захватывать)  ресурсы

22

Взаимоблокировка  (Deadlock)

Взаимоблокировка – такое  состояние  системы,  при  котором  два  или  более  процессов  не  могут  продолжать  своё  выполнение  из-­‐за  отсутствия  необходимых  для  этого  ресурсов.

Каждый  ждёт  другого,  поэтому  никто  не  может  продолжить

23

Выгружаемые  и  невыгружаемые  ресурсы

• Выгружаемые  ресурсы  — ресурсы,  которые  могут быть  безболезненно  отобраны  у  процесса,  который  ими  обладает

• Невыгружаемые  ресурсы  — ресурсы,  которые  нельзяотобрать  у  процесса,  не  вызвав  при  этом  сбой  в  вычислениях

• Мы  будем  говорить,  в  основном,  о  невыгружаемых  ресурсах

24

Операции  над  невыгружаемыми  ресурсами

• Запрос  ресурса- Берём ресурс  - или  ждём (встаём  в  «очередь»  ожидания)

• Использование  ресурса• Освобождение  ресурса

25

Виды  блокирующих  запросов

• без  таймаута• с  таймаутом• с  исключением  (ошибкой)

26

Условия  возникновения  взаимоблокировок

Коффман,  19711. Условие  взаимного  исключения2. Условие  удержания  и  ожидания3. Условие  невыгружаемости4. Условие  циклического  ожидания

27

Условие  взаимного  исключения

Каждый  ресурс  либо  выделен  в  данный  момент только  одному процессу,  либо  доступен для  всех.

28

Условие  удержания  и  ожидания

Процессы,  удерживающие  в  данный  момент  ранее  выделенные  им  ресурсы,  могут запрашивать  новые  ресурсы.

29

Условие  невыгружаемости

Ранее  выделенные  ресурсы  не  могут  быть  принудительно  отобраны у  процесса.  

Они  должны  быть  явным  образом  высвобождены  тем  процессом,  который  их  удерживает.

30

Условие  циклического  ожидания

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

31

Моделирование  взаимоблокировок

Ресурс  занят Запрос  ресурса Взаимоблокировка

32

Моделирование  взаимоблокировок

Ресурс  занят Запрос  ресурса Взаимоблокировка

Граф  ожидания  (Holt,  1972)

33

Пример  графа  ресурсов

34

Условия  возникновения  взаимоблокировок  —ещё  раз

Коффман,  19711. Условие  взаимного  исключения2. Условие  удержания  и  ожидания3. Условие  невыгружаемости4. Условие  циклического  ожидания

Вопрос.  А  в  Java эти  условия  выполняются?

Стратегии  борьбы  с  блокировками

37

Стратегии  борьбы  с  блокировками

• Игнорирование  проблемы• Обнаружение  и  восстановление• Динамическое  уклонение• Предотвращение  за  счёт  подавления  любого  из  четырёх  условий  Коффмана

38

Кто  использует  стратегии  борьбы?

• Базы  данных- Блокировки  на  строках,  таблицах,  индексах  и  т.д.

39

Кто  использует  стратегии  борьбы?

• Базы  данных- Блокировки  на  строках,  таблицах,  индексах  и  т.д.

• JVM

40

Кто  использует  стратегии  борьбы?

• Базы  данных- Блокировки  на  строках,  таблицах,  индексах  и  т.д.

• JVM- А  вот  и  нет!- Ручками,  ручками!

- Ну  и  головой…

41

Алгоритм  Страуса

(Делаем  вид,  что  проблема  отсутствует)• Насколько  часто  возникает  проблема?• Как  часто  возникают  сбои  в  системе  по  другим  причинам?

• Насколько  серьёзны  могут  быть  последствия?

42 Обнаружение  взаимоблокировок  и  восстановление  работоспособности

• Шаги- Позволить  блокировке  произойти- Пытаться  обнаружить  момент  возникновения- Попробовать  восстановить  работоспособность

В  нашем  примере  можно  просто  перезапускать  философов

43

Выход  из  взаимоблокировки

• Приоритетный  захват  ресурсов- Приоритезировать (все)  процессы- Отобрать  ресурс  у  менее  приоритетного  процесса

• Откат  (см.  след.  слайд)• Уничтожение  и  перезапуск  процессов

44

Выход  из  взаимоблокировки  — Откат

• Периодически  создаются  контрольные  точки• При  обнаружении  блокировки  происходит  откат- При  откате  часть  работы  (которая  была  выполнена  после  прохождения  последней  контрольной  точки)  теряется

45

Уклонение  от  взаимоблокировки

• Алгоритм  банкира  (Дейкстра,  1965)• В  основе  — идея  о  траекториях

46

Уклонение  от  взаимоблокировки

• Алгоритм  банкира  (Дейкстра,  1965)• В  основе  — идея  о  траекториях

I,  scheduler

47

Модель  траекторий

48

Предотвращение  взаимоблокировки

• Атака  условия  взаимного  исключения• Атака  условия  ожидания  и  удержания• Атака  условия  циклического  ожидания• Атака  условия  невыгружаемости

49

Атака  условия  взаимного  исключения

• Возможна  редко  — часто  программа  становится  некорректной

• Идея  — убирать  ненужные  блокировки- Делать  нужно  осторожно,  чтобы  функциональность  не  страдала

- Заменять  на  другие  механизмы

50

Атака  условия  ожидания  и  удержания

• Запрашивать   ВСЕ  необходимые  ресурсы  не  в  процессе  работы,  а  до  начала  работы.  - Но  не  всегда  ресурсы  известны  заранее

• Вначале  временно  высвободить  все  удерживаемые  ресурсы

51

Атака  условия  циклического  ожидания

52

Атака  условия  циклического  ожидания

• Нумерация  ресурсов!- Захватывать   ресурсы  только  в  порядке  возрастания  номеров

1

2 3

4

51

2

3

4

5

Demo  2.  Нумерация  ресурсов

54

Голодание    (Starvation)

• Голодание— ситуация,  в  которой  поток,  от  которого  ожидается  прогресс,  (практически)  стоит  на  месте.

55

Голодание    (Starvation)

• Голодание— ситуация,  в  которой  поток,  от  которого  ожидается  прогресс,  (практически)  стоит  на  месте.

• Заблуждение- Голодание  может  осуществиться,  только  если  потоки  с  более  высоким  приоритетом  постоянно  берут  ресурсы,  которые  нужны  голодающему  потоку

56

Атака  условия  невыгружаемости

• Разрешить  выгружать!

57

Атака  условия  невыгружаемости

• Разрешить  выгружать!

• Что  есть  для  этого  в  Java?

58

Lock.tryLock

59

60

Что  же  делать

• Решение  с  посредником: официант  решает,  кому  можно  брать  вилку,  а  кому  нет- Решение  с  общим  критическим  ресурсом- Решение  с  семафором

Demo  3.  Решения  с  официантом

62

И  все-­таки  бенчмарки…

5  потоков  по  2 секунды

eat thinkOrdered  Locks

Common  Unfair  Lock

Common  Fair  Lock Semaphore

0ms 0ms 25 000 000 55 000 000 450 000 11 000 0000ms 1ms 7 900 7 700 7 500 4 0001ms 0ms 1 600 1 500 1 500 1 7001ms 1ms 3 100 1 500 1 500 2 700

Вопросы  и  ответы

Перерыв

Атомики,  CAS  и  неблокирующие  алгоритмы

66

67

Мотивация  бизнеса

68

Модели

• Модель  с  разделяемой  памятью- Регистры- Операции:  read,  write

- Удобно  программировать,  все  привыкли• Модель  с  передачей  сообщений- Послать  сообщение- Похожа  на  то,  как  реально  работает  железо

69

Терминология

• Нет  устоявшейся  терминологии• Термины:• Parallel- Concurrent- Distributed

70

Виды  параллелизма

• На  уровне  операционной  системы• На  уровне  одной  программы  /  процесса

71

Параллелизм  — ОС

- Слушать  музыку  и  переписыватьсяв  фейсбуке в  Одноклассниках

- При  зависании  одной  программы  другие  продолжают  работать

- и  т.п.

72

Преимущества  параллелизма

• Использование  нескольких  ядер/процессоров- Да  и  на  1  ядре  тоже!  (async I/O)

• Простота  моделирования- Абстракция:  фреймворк забирает  сложность

• Упрощенная  обработка  асинхронных  событий• Более  отзывчивые  интерфейсы  пользователя- Event  Dispatch  Thread  (EDT),  async calls

73

Параллелизм  на  уровне  отдельно  взятой  программы

• Эффективное  использование  ресурсов• Удобство,  простота  написания  кода• Справедливость  - Обработка  запросов  пользователей  на  серверах  соцсети с  одинаковым  приоритетом

- Читатели  и  писатели- Fairness  (честность)

74

Lock lock = new ReentrantLock(true);

75

Честность!

Lock lock = new ReentrantLock(true);

76

Честность!

Lock lock = new ReentrantLock(true);

77

Блокировки

• java.util.concurrent— since  Java  5- Lock —> ReentrantLock- ReadWriteLock —> ReentrantReadWriteLock

- StampedLock — since Java 8• Synchronized  method  /  section• wait() / notify() / notifyAll()

78

Блокировки

• java.util.concurrent— since  Java  5- Lock —> ReentrantLock- ReadWriteLock —> ReentrantReadWriteLock

- StampedLock — since Java 8• Synchronized  method  /  section• wait() / notify() / notifyAll()

Общее: ожидание

79

Проблемы  блокировок

• Взаимоблокировки  (Deadlocks)• Инверсия  приоритетов• Надежность  — вдруг  владелец  блокировки  помрет?• Performance- Параллелизма  в  критической  секции  нет!- Владелец  блокировки  может  быть  вытеснен  планировщиком

80

Закон  Амдала

• α — часть общего объема вычислений, которую нельзя распараллелить

• 1-α — часть, которую можно распараллелить

• p — количество потоков

81

Закон  Амдала

• α — часть общего объема вычислений, которую нельзя распараллелить

• 1-α — часть, которую можно распараллелить

• p — количество потоков

Неблокирующие  алгоритмы

83

Классификация

• Без  препятствий  (Obstruction-­‐Free)  — поток  совершает  прогресс,  если  не  встречает  препятствий  со  стороны  других  потоков

• Без  блокировок  (Lock-­‐Free)— гарантируется  системный  прогресс  хотя  бы  одного  потока

• Без  ожидания (Wait-­‐Free) — каждая  операция  выполняется  за  фиксированное  число  шагов,  не  зависящее  от  других  потоков

84

Консенсус

• Объект  consensus  с  операцией  decide(v):- consensus.decide(v)  ≠  const- wait-­‐free

• N  Потоков  вызывают  consensus.decide()- i-­‐ый поток  вызывает  consensus.decide(vi)- Каждый  поток  вызывает  не  более  1  раза- decide() возвращает  одно  из  vi

• decide()  — протокол  консенсуса

85

Консенсусное число

• Мощность  консенсуса  —максимальное  количество  (N) потоков,  для  которых  данный  объект  обеспечивает  консенсус

• Консенсусное число  примитива  синхронизации  —максимальная  мощность  консенсуса,  который  можно  построить  на  базе  данного  примитива и  некоторого  количества  атомарных  регистров- То  есть,  существует  реализация  метода  decide  для  N  потоков,  использующая  данный  примитив  как  строительный  блок

86

Консенсусные числа  различных  операций

• Операции  на  регистрах  — 1• Read-­‐Modification-­‐Write  (RMW) — 2- Common2  Class — коммутируют  друг  с  другом  или  перезаписывают  друг  друга

- Универсальные  операции  —∞- Сравнение  с  обменом  (CAS):  Compare-­‐And-­‐Swap,  Compare-­‐And-­‐Set

87

Compare  and  Swap

• Compare-and-swap (CAS)- IA32, x64 - SPARC

• load-linked / store-conditional (LL/SC)- PowerPC- ARM

88

Семантика  CAS

89

CAS  Loop  — типичный  паттерн  применения

1. Прочитать  значение  A  из  переменной  V2. Взять  какое-­‐то  новое  значение  B  для  V3. Использовать  CAS  для  атомарного  изменения  V  из  A  

в  B до  тех  пор,  пока  другие  потоки  меняют  значение  V  во  время  этого  процесса

Атомарность Read-­‐Modify-­‐Write  реализуется  за  счет  постоянного  мониторинга системы  на  предмет  постороннего  вмешательства

90

Алгоритм  1:  неблокирующий  счетчик

91

Fast  vs.  slow  path

• Каждый  блок  кода  может  иметь,  как  минимум,  два  пути  исполнения:  короткий  и  длинный

• Lock:  contended  vs.  Uncontended• Uncontended  Lock:- ≥  1  CAS

92

Недостатки  CAS

• CAS  заставляет  потоки,  которые  его  вызывают,  работать  в  условиях  соревнования  (contention)- Больше  contention  =  больше  бесполезных  циклов  процессора,  трата  процессорного  времени

• Написание  корректных  и  быстрых  алгоритмов  на    CAS  требует  специальной  подготовки

Поддержка  в  Java

94

Поддержка  CAS  в  Java

• В  Java  5  появился  JSR166- пакет  java.util.concurrent- пакет  java.util.concurrent.atomic

• На  платформах,  поддерживающих  CAS,  JIT-­‐компилятор  делает  inline  соответствующих  машинных  инструкций

• Load  Linked  /  Store  Conditional  

95

Atomic  variable  classes

• Scalars• Field  updaters• Arrays• Compound  variables• Accumulators- since  Java  8

96

Scalars

• AtomicBoolean• AtomicInteger• AtomicLong• AtomicReference

97

AtomicInteger

• boolean compareAndSet(int expect, int update)• int addAndGet(int delta)• int getAndDecrement()• int getAndIncrement()• int incrementAndGet()• …

98

AtomicInteger

• boolean compareAndSet(int expect, int update)• int addAndGet(int delta)• int getAndDecrement()• int getAndIncrement()• int incrementAndGet()• …

Эти  операции  — блокирующие?

99

Multivariable  Invariant

100

Multivariable  Invariant

101

Field  Updaters

• AtomicIntegerFieldUpdater- Reflection-­‐based  updater  for  volatile  int

• AtomicLongFieldUpdater- Reflection-­‐based  updater  for  volatile  long

• AtomicReferenceFieldUpdater

- Reflection-­‐based  updater  for  volatile  object

102

AtomicLongFieldUpdater

- long  addAndGet(T  obj,  long  delta)

- boolean compareAndSet(T  obj,  long  expect,   long  update)

- long  getAndAdd(T  obj,  long  delta)

- long  incrementAndGet(T  obj)

103

AtomicLongFieldUpdater

104

AtomicLongFieldUpdater

105

AtomicArrays

• AtomicIntegerArray• AtomicLongArray• AtomicReferenceArray

106

AtomicLongArray

• long addAndGet(int i, long delta)• long getAndAdd(int i, long delta)• boolean compareAndSet(int i, long expect, long update)

• long incrementAndGet(int i)• …

107

Compound  Variables

• AtomicMarkableReference- compareAndSet(V expectedReference, V newReference,boolean expectedMark, boolean newMark)

• AtomicStampedReference- boolean compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp)

108

Accumulators

• DoubleAccumulator• DoubleAdder• LongAccumulator• LongAdder• (Striped64)

109

LongAccumulator

• void accumulate(long x)• long get()• long getThenReset()• Void reset()

110

• Алгоритм  называется  неблокирующим  (nonblocking),  если  отказ  или  остановка  любого  потока  не  может  привести  к  отказу  или  остановке  любого  другого  потока

• Алгоритм  называется  свободным  от  блокировок (lock-­‐free),  если  на  каждом  шаге  какой-­‐то  поток  выполняет  работу  (make  progress)

• nonblockingи  lock-­‐free  — это  разные  вещи!- Алгоритмы  на  CAS  могут быть  одновременно  неблокирующими  и  свободными  от  блокировок  

110

Неблокирующие  алгоритмы

111

Неблокирующий  стек

112

Неблокирующий  стек

113

Неблокирующий  стек

114

Неблокирующая  очередь

• Michael  and  Scott,  1996• Потоки  помогают друг  другу

Литература

116

117

118

119

DL  и  все-­все-­все

http://altair.cs.oswego.edu/mailman/listinfo/concurrency-­‐interest

To  post  a  message  to  all  the  list  members,  send  email toconcurrency-­‐[email protected]

120Много  полезных  видео

121

https://bitbucket.org/23derevo/concurrency

Вопросы  и  ответы

Спасибо  за  внимание!

@[email protected]@corp.mail.ru