Интернет магазин китайских планшетных компьютеров



Компьютеры - Состояние гонки

23 января 2011


Оглавление:
1. Состояние гонки
2. Случай с Therac-25
3. Взломы путём эксплуатирования состояния гонки



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

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

Пример

Рассмотрим пример кода

  int x;
// Поток 1:
while 
{
  x++;
  …
}
// Поток 2:
while 
{
  if 
    System.out.println;
  …
}

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

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

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

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

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

// Поток 2:
while 
{
  int cached_x = x;
  if 
    System.out.println;
  …
}

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

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

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

int x;
// Поток 1:
while 
{
  synchronized
  {
    x++;
  }
  …
}
// Поток 2:
while 
{
  synchronized
  {
    if 
      System.out.println;
  }
  …
}

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

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

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

long x;
// Поток 1:
while 
{
  synchronized
  {
    x++;
  }
  …
}
// Поток 2:
while 
{
  long cached_x;
  synchronized 
  {
    cached_x = x;
  }
  if 
    //System.out.println;
    DoSomethingComplicated;
  …
}

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



Просмотров: 2732


<<< Семафор (информатика)