Иллюстрированный самоучитель по Visual Studio.Net


Стратегии решения проблемы - часть 2


//====== Обработка сообщений таймера

void CMyWnd::OnTimer(UINT nID)

{

//====== Счетчик попыток

static int iTrial = 0;

//====== Переход по идентификатору таймера

switch (nID)

{

//== Здесь могут быть ветви обработки других таймеров

case WAIT_ID:

//====== Если не удалось открыть

if (ITryOpenO)

{

//===== и запас терпения не иссяк,

if (++iTrial < 10)

return; // то продолжаем ждать

//=== Если иссяк, то сообщаем о полной неудаче

else

{

MessageBox ("Файл занят более 10 секунд",

"Ошибка"); //====== Отказываемся ждать

KillTimer(WAIT_ID);

//====== Обновляем запас терпения

iTrial = 0;

}

}

}

}

Существуют многочисленные варианты рассмотренной проблемы, и в любом случае программист должен решать их, например путем синхронизации доступа к разделяемым ресурсам. Большинство коммерческих систем управления базами данных умеют заботиться о целостности своих данных, но и вы должны обеспечить целостность данных своего приложения. Здесь существуют две крайности: отсутствие защиты или ее слабость и избыток защиты. Вторая крайность может создать низкую эффективность приложения, замедлив его работу так, что им невозможно будет пользоваться. Например, если в примере с повышением зарплаты первый поток заблокирует-таки доступ к записи, но затем начинает вычислять новое значение зарплаты, обратившись к источнику данных о средней (в отрасли) зарплате по всей стране. Такое решение проблемы может привести к ситуации, когда второй поток процесса, который готов корректировать эту же запись, будет вынужден ждать десятки минут.

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

Примечание

Каждое решение создает новые проблемы, а поиск оптимального баланса ложится на плечи программиста, делая его труд еще более интересным. Кстати, последнее решение может вызвать ситуацию, сходную с той, когда два человека уступают друг другу дорогу. Отметьте, что решение вопроса кроется в балансе между производительностью (performance) и целостностью данных (data integrity).




Начало  Назад  Вперед



Книжный магазин