Скачиваний:
50
Добавлен:
23.04.2022
Размер:
4.96 Mб
Скачать

заключающееся в появлении «неразумного»

результата

у Y

при x X и нормальной работе управляющей

ЭВМ и

других

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

Неслучайные отказы ПО обусловлены действием так называемых компьютерных вирусов.

Случайные отказы ПО наблюдаются в случайные моменты времени работы ЭВМ, хотя при этом причины возникновения отказов могут быть и не случайными, например обусловлены появлением определенных сочетаний кодов входной информации х, наличием ошибок в ПО и т. д. По своим последствиям эти отказы классифицируются на случайные сбои программ и устойчивые отказы.

Под сбоем ПО понимают случайное событие, заключающееся в появлении «неразумного» результата у Y и исчезающее при последующих прогонах (запусках) программ. Иными словами, сбой ПО есть самоустраняющийся отказ программы, возникающий при некоторых, возможно случайных, состояниях ЭВМ и информации x X, наблюдаемый пользователем в случайные моменты времени и исчезающий без вмешательства программиста.

Устойчивый отказ ПО наблюдается в случайный момент времени в форме «неразумного» результата y Y при x X и нормальном функционировании ЭВМ. Причиной отказа ПО служит некоторая систематическая ошибка программы, после устранения которой программистом данный отказ исчезает, т. е. имеет место восстановление ПО.

Различают ошибки первичного и вторичного типа. Первые из них связаны с неточностями в текстах программ и возникают при подготовке носителей и документации ПО, при записях кодов на алгоритмических языках и трансляции программ на машинный язык. Первичные ошибки появляются также из-за неточностей алгоритмов и при неверных или некорректных постановках решаемых задач.

Ошибки вторичного типа во многом являются следствием первичных ошибок программ. К ним относят ошибки:

вычислительные (расхождение результатов ручного и машинного счетов, неустойчивость и т. п.);

логические (пропуск логических условий, неверные краевые условия и т. п.);

441

манипулирования данными (изменение формата, нарушение границ изменения сигналов и т. д.);

сопряжения интерфейсов (межмодульных, программно-тех- нических, информационных).

Ошибки первичного и вторичного типа порождаются на этапах разработки спецификаций на ПО, проектирования ПО и особенно реализации программ. Устранение ошибок или восстановление программ осуществляется программистом на этапе отладки ПО. Формально считается, что ПО корректно и исправно в том смысле, что оно удовлетворяет спецификациям и все тестовые задачи решаются правильно. Как показывает опыт исследования надежности сложных ПО, около половины ошибок программ не выявляются на стадии отладки и сдачи ПО в эксплуатацию. Эти ошибки (преимущественно вторичные) проявляют себя в процессе эксплуатации ПО

вслучайные моменты времени t и приводят к отказам программ. Отказ ПО не приводит к разрушению или поломке программ-

ного элемента. Отказы ПО не связаны с физическим износом элемента (в частности, носителя программы). При длительной эксплуатации ПО все его ошибки могут быть устранены и программы становятся абсолютно надежными. Если обозначить через N(t) число невыявленных ошибок ПО в произвольный момент процессорного времени t, то формально имеет место соотношение lim N(t) = 0, справедливое при условии, что в процессе восстановления программ в них не вносятся новые ошибки (рис. 9.4).

N

N(0)

N(t) N1(t) N2(t)

t

Рис. 9.4. Зависимость числа ошибок программного обеспечения от времени эксплуатации

442

Зависимость N(t), изображенная на рис. 9.4, носит теоретический характер, ибо, как показывает опыт создания и эксплуатации ПО реального времени, при устранении одних ошибок вносятся другие. Вследствие этого при длительной эксплуатации ПО общее число скрытых ошибок может оставаться почти постоянным или даже возрастать (пунктирные кривые N1(t) и N2(t) на рис. 9.4).

Для описания надежности ПО используют такие же функциональные и числовые характеристики, как и при исследовании надежности технических систем: P(t), Q(t), λ(t), T0. Однако необходимо отметить, что модели расчета надежности ПО зачастую не учитывают влияния времени, затрачиваемого на принятие решения после его отказа. Не учитывается обычно и допустимое время на принятие решения, сверх которого ПО попадает в отказовое состояние. В силу этого значения показателей надежности, таких как коэффициент готовности, бывают неоправданно завышенными. Время на принятие решения может оказать существенное влияние на надежность системы, что необходимо учитывать при ее проектировании.

Основная особенность характеристик надежности ПО заключается в их зависимости от числа ошибок N(0), имеющихся в программах после сдачи их в эксплуатацию, т. е. при t = 0. Если считать, что при восстановлении ПО новые ошибки не вносятся

и lim N (t) = 0, то интенсивность отказов будет зависеть от N(0)

t →∞

и уменьшаться по мере устранения ошибок. Это допущение приводит к появлению семейства распределений P(t), зависящих от N(0) (см. рис. 9.4).

Зависимость λ(t) может быть описана формулой

λ(t) = λ0[N(0) – j], tj–1 t < tj,

(9.2)

где λ0 – константа; N(0) – число ошибок в ПО при t = 0; j – порядковый номер обнаруженной ошибки, j = 1,2,…, N(0); tj – момент времени обнаружения j-й ошибки.

Функция надежности в этом случае будет определяться зависимостью

P(t) = exp {– λ0[N(0) – j]t}, tj–1 t < tj,

443

которая при j N(0) будет стремиться к единице, т. е. ПО рано или поздно становится абсолютно надежным. Для определения λ(t), P(t) важно знать N(0). Для нахождения оценки N*(0) чаще всего проводят вычислительный эксперимент, заключающийся во внесении в ПО некоторого числа ∆N дополнительных или искусственных ошибок и последующем выявлении N1 собственных и ∆N1 дополнительных ошибок (здесь N1N(0) и ∆N1≤ ∆N). Тогда согласно методу максимального правдоподобия имеем

N*(0) = ∆N N1/∆N1.

(9.3)

Подобный прием позволяет получить относительно хорошую оценку N*(0) только в том случае, если искусственно добавленные ошибки достаточно типичны или «похожи» на собственные ошибки ПО. Однако из-за слабой изученности природы собственных ошибок ПО именно создание типичных ошибок и их размещение внутри программы вызывает серьезные затруднения.

Если ПО достаточно сложное, то в первом приближении допустимо считать, что

λ(t) = λ0[N(0)] = λ = const

и характеризовать надежность ПО показателями

P(t) = exp {– λt}, f (t) = λexp {– λt}, T0 = λ–1.

Применение экспоненциального закона имеет определенное физическое обоснование. Оно связано с тем, что при эксплуатации сложных ПО восстановление отдельных программ неизбежно ведет к внесению новых ошибок и ухудшению качества программ, поэтому общее число невыявленных ошибок N(t) не стремится к нулю, а остается постоянным или возрастающим (кривая N2(t) на рис. 9.4). В последнем случае оценка интенсивности λ*(t) может оказаться постоянной величиной λ.

9.4. Оценка надежности программ по наработке (модель Шумана)

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

444

Модель основана на следующих допущениях:

в начальный момент компоновки программ в систему программного обеспечения в них имеется Е ошибок; в ходе корректировок новые ошибки не вносятся;

общее число I машинных команд в программах постоянно;

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

λ = Сε(τ) = [Е/I – εс(τ)]С,

где εс(τ) – отношение числа ошибок, устраненных в течение времени отладки τ, к общему числу команд на машинном языке.

Таким образом, в модели различаются два значения времени: время отладки τ (обычно измеряется месяцами) и время работы программы t – суммарная наработка программы (часы, доли часа). Время отладки включает затраты времени на выявление ошибок с помощью тестов, контрольные проверки и т. п. Время исправного функционирования при этом не учитывается.

Значение интенсивности отказов считается постоянным в течение всего времени функционирования (0, t). Значение λ изменяется лишь при обнаружении и исправлении ошибок (при этом время t вновь отсчитывается от нуля). В этом случае вероятность отсутствия ошибок программ в течение наработки (0, t)

P(t, τ) = exp{–C[E/I – εс(τ)]t}.

(9.4)

Средняя наработка программы до отказа

Т1 = 1/ λ = 1/{[E/I – εс(τ)]С}.

Для практического использования формулы (9.4) необходимо оценить С и Е по экспериментальным данным. Для этого можно ис-

пользовать метод моментов или метод максимального правдоподобия.

Применяя метод моментов и рассматривая два периода отладки программ τ1 и τ2 при τ1 < τ2, получаем:

E =

I[γ εc (τ1 )−εc (τ2 )]

, γ = t n

2

(t

2

n );

 

 

γ −1

1

 

1

 

 

 

 

 

 

445

 

 

 

 

n1

 

 

 

C

 

=

t

[E I − ε

c

(τ )],

(9.5)

 

 

1

 

1

 

где t1, t2 – продолжительности работы системы, соответствующие

τ1 и τ2; n1, n2 – число ошибок в ПО, обнаруженных соответственно в периодах τ1 и τ2.

9.5. Оценка надежности программ по числу прогонов (модель Нельсона)

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

Модель строится на основе следующих простых соображений:

машинная программа П может быть определена как описание некоторой вычисляемой функции F на множестве Е всех значений наборов входных данных, таких, что каждый элемент Ei множества Е представляет собой набор значений данных, необходимый для выполнения прогона программы: Е = (Ei: i = 1:N);

выполнение программы П приводит к получению для каждого Ei определенного значения функции F(Ei);

множество Е определяет все возможные вычисления в про-

грамме, т. е. каждому набору входных данных Ei соответствует некоторый прогон П, и, наоборот, каждому прогону соответствует некоторый набор входных данных Ei;

наличие дефектов в программе П приводит к тому, что ей на самом деле соответствует функция F', отличная от заданной функции F;

для некоторого Ei отклонение

выхода F'(Ei), получаемого

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

от желаемого значения F(Ei)

находится в допустимых пределах ∆i, т. е. |F'(Ei) – F(Ei)| ≤ ∆i;

446

для всех остальных Ei, образующих подмножество Eе множества Е, выполнение программы П не обеспечивает приемлемого результата, т. е.

|F'(Ei) – F(Ei)| > ∆I ,

либо работа программы прекращается преждевременно или выполнение программы не может закончиться (программа зацикливается). Все такие случаи называются рабочими отказами.

Совокупность действий, включающая ввод Ei, выполнение программы П, которое оканчивается получением результата F'(Ei) или рабочим отказом, называется прогоном программы П. Заметим, что значения входных переменных, образующие Ei, не должны все одновременно подаваться на вход программы П. Таким образом, вероятность Р того, что прогон программы П приведет к рабочему отказу, равна вероятности, что набор входных данных Ei, используемый

вданном прогоне, принадлежит множеству Eе.

Втакой модели за показатель надежности программы принимается вероятность P(n) безотказного выполнения n прогонов программы.

Вероятность того, что j-й прогон закончится отказом,

N

 

Q = p ji yi ,

(9.6)

i=1

где pji – вероятность выбора i-го набора входных данных при j-м прогоне из некоторой последовательности прогонов; yi – «динамическая переменная», принимающая значение 0, если прогон программы при i-м наборе входных данных оказывается успешным, и значение 1, если этот прогон заканчивается отказом; N – число возможных наборов входных данных. Для n прогонов

P(n)= ∏n (1Qj ).

j=1

Таким образом, можно дать следующее определение надежно-

сти машинной программы: надежность программы – это вероятность безотказного выполнения n прогонов программы. Поэтому прогон является единичным испытанием программы.

447

На практике надежность программы может быть оценена путем прогона программы на n наборах входных данных и вычисления значения оценки

Р* = 1–nе/n,

(9.7)

где nе – число наборов входных данных, при которых произошли отказы.

Чтобы установить связь между моделями по наработке и по прогонам, запишем

n

n

 

 

P(n)= ∏(1

Qj ) или P(n) = exp ln(1− Q j ) .

(9.8)

j=1

j =1

 

 

 

 

 

 

Обозначим ∆tj – время выполнения j-го прогона программы,

j

t j = ti – суммарное время выполнения первых j прогонов про-

i=1

граммы и примем, что

λ(tj) = –ln(1–Qj)/∆tj.

При этом

n

 

 

P(n) = exp

t jλ(t j ) .

(9.9)

j =1

 

 

 

 

 

При Qj << 1 функция λ(tj) может рассматриваться как функция интенсивности отказов.

9.6. Повышение надежности программного обеспечения

Программное обеспечение состоит из большого числа программ, подпрограмм и модулей, находящихся под управлением операционной системы реального времени или программыдиспетчера. Выполнение каждой из этих программ осуществляется последовательно во времени на одном и том же процессоре. Если эти программы имеют взаимные информационные связи или предназначены для получения одного результата y (вычисления одной функции), то в надежностном отношении такой программный комплекс представляет собой простую систему без избыточности и вероятность его безотказной работы равна

448

m

Pji (t)= Pi (t),

i=1

где m – общее число программ.

Надежность такого ПО определяется интенсивностью отказов самой «ненадежной» программы, имеющей наибольшее значение λi, i = 1:m. Для повышения надежности нерезервированного ПО следует в первую очередь улучшить характеристики самых «ненадежных» программ. Для этого на этапе отладки и сдачи ПО в эксплуатацию осуществляют более жесткое динамическое тестирование «ненадежных» программ, расширяя при этом набор тестовых задач. Если тестирование не уменьшает интенсивность появления ошибок, то переписывают «ненадежную» программу, стремясь усилить ее структурированность путем увеличения числа готовых и хорошо изученных программных модулей и стандартных подпрограмм и применения апробированных межмодульных интерфейсов. Понижению интенсивности λi способствует и переход на другой более высокий язык программирования.

Другой путь повышения надежности ПО реального времени связан с резервированием и введением в систему некоторой избыточности. Различают три вида резервирования:

временное;

информационное;

программное.

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

449

Информационное резервирование ПО основано на дублировании исходных х и промежуточных данных. Эти данные могут проходить дополнительную обработку, например усреднение, до ввода в ПО, где они обрабатываются один раз; или обрабатываться одной и той же программой дважды, т. е. информационное резервирование подкрепляется временным. Такой способ резервирования ведет к усложнению алгоритмов обработки информации и самого ПО и поэтому не получил широкого распространения.

Программное резервирование предусматривает наличие в ПО двух или больше разных программ для получения одного и того же результата y или реализации одной функции. Здесь возможно нагруженное и ненагруженное резервирование. В первом случае исходная информация х постоянно обрабатывается двумя различными программами, результаты действия которых y1 и y2 сравниваются, и если они близки в определенном смысле, то их среднее значение вводится в последующие программы, в противном случае подается сигнал о появлении ошибки ПО. При нагруженном резервировании функционирует только одна основная программа, обрабатывающая сигнал х, и специальная программа-индикатор. Если результат y1 действия основной программы вызывает «подозрения» у индикатора, то исходная информация х вводится в резервную программу, результат y2 которой снова анализируется индикатором. При близости y1 и y2 их среднее значение y передается последующим программам, в противном случае фиксируется ошибка основной программы.

Рассмотрим пример функционирования двух программ, граф состояний работы которых представлен на рис. 9.5. Предполагается, что восстановление любой из отказавших программ начинается только после принятия решения по ней. Отказ наступает только в двух ситуациях: произошел отказ обеих программ или время принятия решения после отказа некоторой программы оказалось больше, чем допустимое. В этом случае мы имеем следующие состояния функционирования ПО:

(0) – работает первая программа;

(1) – произошел отказ первой программы, расходуется время на принятие по первой программе, расходуется допустимое время;

(2) – произошел отказ первой программы, расходуется время на принятие решения по первой программе, допустимое время полностью израсходовано;

450