Состояние гонки

Состояние гонки

Состоя́ние го́нки (англ. race condition) — ошибка проектирования многопоточной системы или приложения, при которой работа системы или приложения зависит от того, в каком порядке выполняются части кода. Своё название ошибка получила от похожей ошибки проектирования электронных схем (см. Гонки сигналов (электроника)).

Состояние гонки — специфическая ошибка, проявляющаяся в случайные моменты времени и «затихающая» при попытке её локализовать.

Содержание

Пример

Рассмотрим пример кода (на Java)[1]

  int x;
// Поток 1:
while (!stop)
{
  x++;}
// Поток 2:
while (!stop)
{
  if (x%2 == 0)
    System.out.println("x=" + x);}

Пусть x=0. Предположим, что выполнение программы происходит в таком порядке:

  1. if в потоке 2 проверяет x на чётность.
  2. Оператор «x++» в потоке 1 увеличивает x на единицу.
  3. Оператор вывода в потоке 2 выводит «x=1», хотя, казалось бы, переменная проверена на чётность.

Способы решения

Локальная копия

Самый простой способ решения — копирование переменной x в локальную переменную. Вот исправленный код:

// Поток 2:
while (!stop)
{
  int cached_x = x;
  if (cached_x%2 == 0)
    System.out.println("x=" + cached_x);}

Естественно, этот способ работает только тогда, когда переменная одна и копирование производится за одну машинную команду.

Синхронизация

Более сложный, но и более универсальный метод решения — синхронизация потоков, а именно:[1]

int x;
// Поток 1:
while (!stop)
{
  synchronized(SomeObject)
  {
    x++;
  }}
// Поток 2:
while (!stop)
{
  synchronized(SomeObject)
  {
    if (x%2 == 0)
      System.out.println("x=" + x);
  }}

Комбинированный способ

Предположим, что переменная x имеет тип не int, а long (на 32-битных ЭВМ её копирование выполняется за две машинных команды), а во втором потоке вместо System.out.println стоит более сложная обработка. В этом случае оба метода неудовлетворительны: первый — потому что x может измениться, пока идет копирование; второй — потому что засинхронизирован слишком большой объём кода.

Эти способы можно скомбинировать, копируя «опасные» переменные в синхронизированном блоке. С одной стороны, это снимет ограничение на одну машинную команду, с другой — позволит избавиться от слишком больших синхроблоков.

long x;
// Поток 1:
while (!stop)
{
  synchronized(SomeObject)
  {
    x++;
  }}
// Поток 2:
while (!stop)
{
  long cached_x;
  synchronized (SomeObject)
  {
    cached_x = x;
  }
  if (cached_x%2 == 0)
    //System.out.println("x=" + cached_x);
    DoSomethingComplicated(cached_x);}

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

Случай с Therac-25

Аппарат лучевой терапии Therac-25 был первым в США медицинским аппаратом, в котором вопросы безопасности были возложены исключительно на программное обеспечение. Этот аппарат работал в трёх режимах:

  1. Электронная терапия: электронная пушка напрямую облучает пациента; компьютер задаёт энергию электронов от 5 до 25 МэВ.
  2. Рентгеновская терапия: электронная пушка облучает вольфрамовую мишень, и пациент облучается рентгеновскими лучами, проходящими через конусообразный рассеиватель. В этом режиме энергия электронов одна: 25 МэВ.
  3. В третьем режиме никакого излучения не было. На пути электронов (на случай аварии) располагается стальной отражатель, а излучение имитируется светом. Этот режим применяется для того, чтобы точно навести пучок на больное место.

Эти три режима задавались вращающимся диском, в котором было отверстие с отклоняющими магнитами для электронной терапии, и мишень с рассеивателем для рентгеновской. Из-за состояния гонки между управляющей программой и обработчиком клавиатуры иногда случалось, что в режиме рентгеновской терапии диск оказывался в положении «Электронная терапия», и пациент напрямую облучался пучком электронов в 25 МэВ, что вело к переоблучению. При этом датчики выводили «Нулевая доза», поэтому оператор мог повторить процедуру, усугубляя ситуацию. В результате погибли как минимум четыре пациента.

Часть кода была взята из Therac-6 и Therac-20. При этом в Therac-6 не было рентгеновской терапии, а в Therac-20 были аппаратные меры безопасности, которые не давали включить излучение, когда диск был в неправильном положении.

Взломы путём эксплуатирования состояния гонки

Существует класс ошибок (и эксплуатирующих их типов атак), позволяющих непривилегированной программе влиять на работу других программ через возможность изменения общедоступных ресурсов (обычно — вре́менных файлов; англ. /tmp race — состояние гонки во вре́менном каталоге), в определённое временно́е окно, в которое файл по ошибке программиста доступен для записи всем или части пользователей системы.

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

Именно по этой причине ПО с серьёзными требованиями по безопасности, такое, как веб-браузер, использует случайные числа криптографического качества для именования временных файлов.

Примечания

  1. 1 2 Ключевое слово volatile намеренно не поставлено — доступ к переменной с этим модификатором в Java синхронизируется автоматически.

См. также

Ссылки



Wikimedia Foundation. 2010.

Игры ⚽ Нужно решить контрольную?

Полезное


Смотреть что такое "Состояние гонки" в других словарях:

  • Гонки — Гонка соревнование, подразумевающее одновременный старт группы нескольких (двух или более) участников и фиксацию порядка финиша каждого из участников. Особым видом гонок являются матчевые, когда в соревнованиях одновременно участвуют только два… …   Википедия

  • Буря в стакане: Гонки на маршрутках — Разработчики SkyRiver Studios, Божья искра Издатель 1С Создатели Руководитель Валерий Воронин …   Википедия

  • Российская Советская Федеративная Социалистическая Республика, РСФСР (медико-санитарное состояние и здравоохранение) — VII. Медико санитарное состояние и здравоохранение = Здравоохранение. Медицина). В конце 16 в. была организована Аптекарская палата …   Большая советская энциклопедия

  • Поток выполнения — Для термина «Поток» см. другие значения. Процесс с двумя потоками выполнения на одном процессоре Поток выполнения (анг …   Википедия

  • Параллельные вычислительные системы — Не следует путать с Распределённые вычисления. Параллельные вычислительные системы  это физические компьютерные, а также программные системы, реализующие тем или иным способом параллельную обработку данных на многих вычислительных узлах.[1]… …   Википедия

  • Семафор (информатика) — У этого термина существуют и другие значения, см. Семафор. Семафор  объект, позволяющий войти в заданный участок кода не более чем n потокам. Определение введено Эдсгером Дейкстрой. Семафоры используются при передаче данных через разделяемую …   Википедия

  • Мьютекс — (англ. mutex, от mutual exclusion  «взаимное исключение»)  одноместный семафор, служащий в программировании для синхронизации одновременно выполняющихся потоков. Мьютексы  это один из вариантов семафорных механизмов для… …   Википедия

  • Семафор (программирование) — Это статья о методе синхронизации выполняющихся одновременно программ. Остальные значения этого слова описаны в статье Семафор. Семафор объект, позволяющий войти в заданный участок кода не более чем n потокам. Определение введено Э. Дейкстрой.… …   Википедия

  • Взаимная блокировка — двух процессов P1 и P2 нуждающихся в двух ресурсах. Взаимная блокировка (англ. deadlock)  ситуация в многозадачной с …   Википедия

  • Intelligent Platform Management Interface — IPMI (от англ. Intelligent Platform Management Interface)  интеллектуальный интерфейс управления платформой, предназначенный для автономного мониторинга и управления функциями, встроенными непосредственно в аппаратное и микропрограммное …   Википедия


Поделиться ссылкой на выделенное

Прямая ссылка:
Нажмите правой клавишей мыши и выберите «Копировать ссылку»