Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

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

1.820 visualizaciones

Publicado el

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

Доклад сделан на московском JUG 24.09.2015

Publicado en: Ingeniería
  • Sé el primero en comentar

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

  1. 1. Общество  Мертвых  Потоков Алексей  Федоров,   Одноклассники  / JUG.ru
  2. 2. Зачем  вы  здесь?
  3. 3. 3 Чего  не  будет  в  презентации • Определений  из  учебника - Больше  интересует  сама  концепция • Сравнения  производительности • Советов,  как  правильно  писать  код • Холиваров* • Серебряных  пуль,  волшебных  фреймворков и  т.п. *  Нет,  ну  если  кто-­‐то  очень  захочет,  то  можно,  конечно…
  4. 4. 4 А  что  будет-­то? • Пара  простых  многопоточных  примеров • Куча  связанных  с  ними  проблем • Варианты  решений - Которые,  разумеется,  не  работают - Ну  некоторые  работают - Иногда - Наверное…
  5. 5. 5 Пререквизиты Нужно  примерно понимать,  что  такое • Thread • Runnable • synchonized • Lock lock = new ReentrantLock(false) • volatile • AtomicInteger • Compare-And-Set
  6. 6. 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
  7. 7. Проблема  обедающих  философов Dijkstra,  1965 Hoare,  1985 Что  это?
  8. 8. 8 • 5  философов  по  кругу – Тарелка  с  едой  перед  каждым – Вилки  между  тарелками • Каждый  может – Размышлять – Брать  соседнюю  вилку – Есть  (строго  двумя  вилками!) – Класть  одну  вилку Задача  о  философах
  9. 9. 9 Проблемы  с  обедающими  философами Пусть  каждый  философ  действует  по   некоторому  алгоритму • Могут  ли  все  философы  умереть  с   голоду? • Можно  ли  составить  такой   алгоритм,  чтобы  все  философы   гарантированно не  умерли  с   голоду?
  10. 10. 10 Параметры  задачи • Количество  философов • Есть  ли  возможность  положить  вилку,  не  пожрамши • Сколько  времени  философ  ест - Фиксированное  или  случайная  величина • Сколько  времени  философ  размышляет - Фиксированное  или  случайная  величина - Как  это  время  соотносится  с  временем  еды • Какие  ещё  инструменты/элементы  есть  в  системе? • Что  ещё?
  11. 11. 11 Фиксированное  время  и  случайное  время • Случайное  время  задаётся  какой-­‐то  функцией   распределения • Константа  тоже задаётся  функцией  распределения - (А  бывают  ли  вообще  константы  в  реальном  мире?)
  12. 12. 12 Фиксированное  время  и  случайное  время • Случайное  время  задаётся  какой-­‐то  функцией   распределения • Константа  тоже задаётся  функцией  распределения - (А  бывают  ли  вообще  константы  в  реальном  мире?)
  13. 13. Решение
  14. 14. 14 Пронумеруем  философов  и  вилки 1 2 3 4 5 1 2 3 4 5
  15. 15. Demo  1.  Сено-­‐солома
  16. 16. 16 Простое  решение • Когда  философ  хочет  есть,  он  делает  следующие  шаги: 1. Берёт  левую  от  себя  вилку  («сено») 2. Берёт  правую  от  себя  вилку  («солома») 3. Ест 4. Кладёт  одну  вилку 5. Кладёт  другую  вилку 6. Размышляет • И  так  по  кругу
  17. 17. 17 Моделирование  на  Java
  18. 18. 18 Deadlock
  19. 19. 19
  20. 20. Теория
  21. 21. 21 Ресурсы  и  взаимоблокировка Ресурс – объект,  к  которому  предоставляется  доступ Во  время  работы  процесс  может  брать  (захватывать)   ресурсы
  22. 22. 22 Взаимоблокировка  (Deadlock) Взаимоблокировка – такое  состояние  системы,   при  котором  два  или  более  процессов  не  могут   продолжать  своё  выполнение  из-­‐за  отсутствия   необходимых  для  этого  ресурсов. Каждый  ждёт  другого,  поэтому  никто  не  может   продолжить
  23. 23. 23 Выгружаемые  и  невыгружаемые  ресурсы • Выгружаемые  ресурсы  — ресурсы,  которые  могут быть   безболезненно  отобраны  у  процесса,  который  ими  обладает • Невыгружаемые  ресурсы  — ресурсы,  которые  нельзя отобрать  у  процесса,  не  вызвав  при  этом  сбой  в  вычислениях • Мы  будем  говорить,  в  основном,  о  невыгружаемых  ресурсах
  24. 24. 24 Операции  над  невыгружаемыми  ресурсами • Запрос  ресурса - Берём ресурс   - или  ждём (встаём  в  «очередь»  ожидания) • Использование  ресурса • Освобождение  ресурса
  25. 25. 25 Виды  блокирующих  запросов • без  таймаута • с  таймаутом • с  исключением  (ошибкой)
  26. 26. 26 Условия  возникновения  взаимоблокировок Коффман,  1971 1. Условие  взаимного  исключения 2. Условие  удержания  и  ожидания 3. Условие  невыгружаемости 4. Условие  циклического  ожидания
  27. 27. 27 Условие  взаимного  исключения Каждый  ресурс  либо  выделен  в  данный  момент только   одному процессу,  либо  доступен для  всех.
  28. 28. 28 Условие  удержания  и  ожидания Процессы,  удерживающие  в  данный  момент  ранее   выделенные  им  ресурсы,  могут запрашивать  новые   ресурсы.
  29. 29. 29 Условие  невыгружаемости Ранее  выделенные  ресурсы  не  могут  быть  принудительно   отобраны у  процесса.   Они  должны  быть  явным  образом  высвобождены  тем   процессом,  который  их  удерживает.
  30. 30. 30 Условие  циклического  ожидания Должна  существовать  кольцевая  последовательность  из   двух  и  более  процессов,  каждый  из  которых  ожидает   высвобождения  ресурса,  удерживаемого  следующим   членом  последовательности.
  31. 31. 31 Моделирование  взаимоблокировок Ресурс  занят Запрос  ресурса Взаимоблокировка
  32. 32. 32 Моделирование  взаимоблокировок Ресурс  занят Запрос  ресурса Взаимоблокировка Граф  ожидания  (Holt,  1972)
  33. 33. 33 Пример  графа  ресурсов
  34. 34. 34 Условия  возникновения  взаимоблокировок  — ещё  раз Коффман,  1971 1. Условие  взаимного  исключения 2. Условие  удержания  и  ожидания 3. Условие  невыгружаемости 4. Условие  циклического  ожидания
  35. 35. Вопрос.  А  в  Java эти  условия  выполняются?
  36. 36. Стратегии  борьбы  с  блокировками
  37. 37. 37 Стратегии  борьбы  с  блокировками • Игнорирование  проблемы • Обнаружение  и  восстановление • Динамическое  уклонение • Предотвращение  за  счёт  подавления  любого  из   четырёх  условий  Коффмана
  38. 38. 38 Кто  использует  стратегии  борьбы? • Базы  данных - Блокировки  на  строках,  таблицах,  индексах  и  т.д.
  39. 39. 39 Кто  использует  стратегии  борьбы? • Базы  данных - Блокировки  на  строках,  таблицах,  индексах  и  т.д. • JVM
  40. 40. 40 Кто  использует  стратегии  борьбы? • Базы  данных - Блокировки  на  строках,  таблицах,  индексах  и  т.д. • JVM - А  вот  и  нет! - Ручками,  ручками! - Ну  и  головой…
  41. 41. 41 Алгоритм  Страуса (Делаем  вид,  что  проблема  отсутствует) • Насколько  часто  возникает  проблема? • Как  часто  возникают  сбои  в  системе  по   другим  причинам? • Насколько  серьёзны  могут  быть   последствия?
  42. 42. 42 Обнаружение  взаимоблокировок  и   восстановление  работоспособности • Шаги - Позволить  блокировке  произойти - Пытаться  обнаружить  момент  возникновения - Попробовать  восстановить  работоспособность В  нашем  примере  можно  просто  перезапускать  философов
  43. 43. 43 Выход  из  взаимоблокировки • Приоритетный  захват  ресурсов - Приоритезировать (все)  процессы - Отобрать  ресурс  у  менее  приоритетного  процесса • Откат  (см.  след.  слайд) • Уничтожение  и  перезапуск  процессов
  44. 44. 44 Выход  из  взаимоблокировки  — Откат • Периодически  создаются  контрольные  точки • При  обнаружении  блокировки  происходит  откат - При  откате  часть  работы  (которая  была  выполнена   после  прохождения  последней  контрольной  точки)   теряется
  45. 45. 45 Уклонение  от  взаимоблокировки • Алгоритм  банкира  (Дейкстра,  1965) • В  основе  — идея  о  траекториях
  46. 46. 46 Уклонение  от  взаимоблокировки • Алгоритм  банкира  (Дейкстра,  1965) • В  основе  — идея  о  траекториях I,  scheduler
  47. 47. 47 Модель  траекторий
  48. 48. 48 Предотвращение  взаимоблокировки • Атака  условия  взаимного  исключения • Атака  условия  ожидания  и  удержания • Атака  условия  циклического  ожидания • Атака  условия  невыгружаемости
  49. 49. 49 Атака  условия  взаимного  исключения • Возможна  редко  — часто  программа  становится   некорректной • Идея  — убирать  ненужные  блокировки - Делать  нужно  осторожно,  чтобы  функциональность   не  страдала - Заменять  на  другие  механизмы
  50. 50. 50 Атака  условия  ожидания  и  удержания • Запрашивать  ВСЕ  необходимые  ресурсы  не  в   процессе  работы,  а  до  начала  работы.   - Но  не  всегда  ресурсы  известны  заранее • Вначале  временно  высвободить  все  удерживаемые   ресурсы
  51. 51. 51 Атака  условия  циклического  ожидания
  52. 52. 52 Атака  условия  циклического  ожидания • Нумерация  ресурсов! - Захватывать  ресурсы  только  в  порядке   возрастания  номеров 1 2 3 4 5 1 2 3 4 5
  53. 53. Demo  2.  Нумерация  ресурсов
  54. 54. 54 Голодание    (Starvation) • Голодание — ситуация,  в  которой  поток,  от  которого   ожидается  прогресс,  (практически)  стоит  на  месте.
  55. 55. 55 Голодание    (Starvation) • Голодание — ситуация,  в  которой  поток,  от  которого   ожидается  прогресс,  (практически)  стоит  на  месте. • Заблуждение - Голодание  может  осуществиться,  только  если  потоки   с  более  высоким  приоритетом  постоянно  берут   ресурсы,  которые  нужны  голодающему  потоку
  56. 56. 56 Атака  условия  невыгружаемости • Разрешить  выгружать!
  57. 57. 57 Атака  условия  невыгружаемости • Разрешить  выгружать! • Что  есть  для  этого  в  Java?
  58. 58. 58 Lock.tryLock
  59. 59. 59
  60. 60. 60 Что  же  делать • Решение  с  посредником: официант  решает,  кому   можно  брать  вилку,  а  кому  нет - Решение  с  общим  критическим  ресурсом - Решение  с  семафором
  61. 61. Demo  3.  Решения  с  официантом
  62. 62. 62 И  все-­таки  бенчмарки… 5  потоков  по  2 секунды eat think Ordered   Locks Common   Unfair  Lock Common  Fair   Lock Semaphore 0ms 0ms 25 000 000 55 000 000 450 000 11 000 000 0ms 1ms 7 900 7 700 7 500 4 000 1ms 0ms 1 600 1 500 1 500 1 700 1ms 1ms 3 100 1 500 1 500 2 700
  63. 63. Вопросы  и  ответы
  64. 64. Перерыв
  65. 65. Атомики,  CAS  и  неблокирующие  алгоритмы
  66. 66. 66
  67. 67. 67 Мотивация  бизнеса
  68. 68. 68 Модели • Модель  с  разделяемой  памятью - Регистры - Операции:  read,  write - Удобно  программировать,  все  привыкли • Модель  с  передачей  сообщений - Послать  сообщение - Похожа  на  то,  как  реально  работает  железо
  69. 69. 69 Терминология • Нет  устоявшейся  терминологии • Термины: • Parallel - Concurrent - Distributed
  70. 70. 70 Виды  параллелизма • На  уровне  операционной  системы • На  уровне  одной  программы  /  процесса
  71. 71. 71 Параллелизм  — ОС - Слушать  музыку  и  переписываться в  фейсбуке в  Одноклассниках - При  зависании  одной  программы  другие   продолжают  работать - и  т.п.
  72. 72. 72 Преимущества  параллелизма • Использование  нескольких  ядер/процессоров - Да  и  на  1  ядре  тоже!  (async I/O) • Простота  моделирования - Абстракция:  фреймворк забирает  сложность • Упрощенная  обработка  асинхронных  событий • Более  отзывчивые  интерфейсы  пользователя - Event  Dispatch  Thread  (EDT),  async calls
  73. 73. 73 Параллелизм  на  уровне  отдельно  взятой  программы • Эффективное  использование  ресурсов • Удобство,  простота  написания  кода • Справедливость   - Обработка  запросов  пользователей  на  серверах   соцсети с  одинаковым  приоритетом - Читатели  и  писатели - Fairness  (честность)
  74. 74. 74 Lock lock = new ReentrantLock(true);
  75. 75. 75 Честность! Lock lock = new ReentrantLock(true);
  76. 76. 76 Честность! Lock lock = new ReentrantLock(true);
  77. 77. 77 Блокировки • java.util.concurrent— since  Java  5 - Lock —> ReentrantLock - ReadWriteLock —> ReentrantReadWriteLock - StampedLock — since Java 8 • Synchronized  method  /  section • wait() / notify() / notifyAll()
  78. 78. 78 Блокировки • java.util.concurrent— since  Java  5 - Lock —> ReentrantLock - ReadWriteLock —> ReentrantReadWriteLock - StampedLock — since Java 8 • Synchronized  method  /  section • wait() / notify() / notifyAll() Общее: ожидание
  79. 79. 79 Проблемы  блокировок • Взаимоблокировки  (Deadlocks) • Инверсия  приоритетов • Надежность  — вдруг  владелец  блокировки  помрет? • Performance - Параллелизма  в  критической  секции  нет! - Владелец  блокировки  может  быть  вытеснен   планировщиком
  80. 80. 80 Закон  Амдала • α — часть общего объема вычислений, которую нельзя распараллелить • 1-α — часть, которую можно распараллелить • p — количество потоков
  81. 81. 81 Закон  Амдала • α — часть общего объема вычислений, которую нельзя распараллелить • 1-α — часть, которую можно распараллелить • p — количество потоков
  82. 82. Неблокирующие  алгоритмы
  83. 83. 83 Классификация • Без  препятствий  (Obstruction-­‐Free)  — поток  совершает   прогресс,  если  не  встречает  препятствий  со  стороны   других  потоков • Без  блокировок  (Lock-­‐Free) — гарантируется  системный   прогресс  хотя  бы  одного  потока • Без  ожидания (Wait-­‐Free) — каждая  операция   выполняется  за  фиксированное  число  шагов,  не   зависящее  от  других  потоков
  84. 84. 84 Консенсус • Объект  consensus  с  операцией  decide(v): - consensus.decide(v)  ≠  const - wait-­‐free • N  Потоков  вызывают  consensus.decide() - i-­‐ый поток  вызывает  consensus.decide(vi) - Каждый  поток  вызывает  не  более  1  раза - decide() возвращает  одно  из  vi • decide()  — протокол  консенсуса
  85. 85. 85 Консенсусное число • Мощность  консенсуса  — максимальное  количество   (N) потоков,  для  которых  данный  объект   обеспечивает  консенсус • Консенсусное число  примитива  синхронизации  — максимальная  мощность  консенсуса,  который  можно   построить  на  базе  данного  примитива и  некоторого   количества  атомарных  регистров - То  есть,  существует  реализация  метода  decide  для   N  потоков,  использующая  данный  примитив  как   строительный  блок
  86. 86. 86 Консенсусные числа  различных  операций • Операции  на  регистрах  — 1 • Read-­‐Modification-­‐Write  (RMW) — 2 - Common2  Class — коммутируют  друг  с  другом  или   перезаписывают  друг  друга - Универсальные  операции  — ∞ - Сравнение  с  обменом  (CAS):   Compare-­‐And-­‐Swap,  Compare-­‐And-­‐Set
  87. 87. 87 Compare  and  Swap • Compare-and-swap (CAS) - IA32, x64 - SPARC • load-linked / store-conditional (LL/SC) - PowerPC - ARM
  88. 88. 88 Семантика  CAS
  89. 89. 89 CAS  Loop  — типичный  паттерн  применения 1. Прочитать  значение  A  из  переменной  V 2. Взять  какое-­‐то  новое  значение  B  для  V 3. Использовать  CAS  для  атомарного  изменения  V  из  A   в  B до  тех  пор,  пока  другие  потоки  меняют  значение   V  во  время  этого  процесса Атомарность Read-­‐Modify-­‐Write  реализуется  за  счет   постоянного  мониторинга системы  на  предмет   постороннего  вмешательства
  90. 90. 90 Алгоритм  1:  неблокирующий  счетчик
  91. 91. 91 Fast  vs.  slow  path • Каждый  блок  кода  может  иметь,  как  минимум,  два   пути  исполнения:  короткий  и  длинный • Lock:  contended  vs.  Uncontended • Uncontended  Lock: - ≥  1  CAS
  92. 92. 92 Недостатки  CAS • CAS  заставляет  потоки,  которые  его  вызывают,   работать  в  условиях  соревнования  (contention) - Больше  contention  =  больше  бесполезных  циклов   процессора,  трата  процессорного  времени • Написание  корректных  и  быстрых  алгоритмов  на     CAS  требует  специальной  подготовки
  93. 93. Поддержка  в  Java
  94. 94. 94 Поддержка  CAS  в  Java • В  Java  5  появился  JSR166 - пакет  java.util.concurrent - пакет  java.util.concurrent.atomic • На  платформах,  поддерживающих  CAS,  JIT-­‐ компилятор  делает  inline  соответствующих   машинных  инструкций • Load  Linked  /  Store  Conditional  
  95. 95. 95 Atomic  variable  classes • Scalars • Field  updaters • Arrays • Compound  variables • Accumulators - since  Java  8
  96. 96. 96 Scalars • AtomicBoolean • AtomicInteger • AtomicLong • AtomicReference
  97. 97. 97 AtomicInteger • boolean compareAndSet(int expect, int update) • int addAndGet(int delta) • int getAndDecrement() • int getAndIncrement() • int incrementAndGet() • …
  98. 98. 98 AtomicInteger • boolean compareAndSet(int expect, int update) • int addAndGet(int delta) • int getAndDecrement() • int getAndIncrement() • int incrementAndGet() • … Эти  операции  — блокирующие?
  99. 99. 99 Multivariable  Invariant
  100. 100. 100 Multivariable  Invariant
  101. 101. 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. 102. 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. 103. 103 AtomicLongFieldUpdater
  104. 104. 104 AtomicLongFieldUpdater
  105. 105. 105 AtomicArrays • AtomicIntegerArray • AtomicLongArray • AtomicReferenceArray
  106. 106. 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. 107. 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. 108. 108 Accumulators • DoubleAccumulator • DoubleAdder • LongAccumulator • LongAdder • (Striped64)
  109. 109. 109 LongAccumulator • void accumulate(long x) • long get() • long getThenReset() • Void reset()
  110. 110. 110 • Алгоритм  называется  неблокирующим  (nonblocking),  если   отказ  или  остановка  любого  потока  не  может  привести  к   отказу  или  остановке  любого  другого  потока • Алгоритм  называется  свободным  от  блокировок(lock-­‐free),   если  на  каждом  шаге  какой-­‐то  поток  выполняет  работу   (make  progress) • nonblocking и  lock-­‐free  — это  разные  вещи! - Алгоритмы  на  CAS  могут быть  одновременно   неблокирующими  и  свободными  от  блокировок   110 Неблокирующие  алгоритмы
  111. 111. 111 Неблокирующий  стек
  112. 112. 112 Неблокирующий  стек
  113. 113. 113 Неблокирующий  стек
  114. 114. 114 Неблокирующая  очередь • Michael  and  Scott,  1996 • Потоки  помогают друг  другу
  115. 115. Литература
  116. 116. 116
  117. 117. 117
  118. 118. 118
  119. 119. 119 DL  и  все-­все-­все http://altair.cs.oswego.edu/mailman/listinfo/concurrency-­‐interest To  post  a  message  to  all  the  list  members,  send  email to concurrency-­‐interest@cs.oswego.edu
  120. 120. 120 Много  полезных  видео
  121. 121. 121 https://bitbucket.org/23derevo/concurrency
  122. 122. Вопросы  и  ответы
  123. 123. Спасибо  за  внимание! @23derevo alexey@jugru.org alexey.fyodorov@corp.mail.ru

×