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




Стратегии решения проблемы


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

//======= Создаем объект класса CFile

CFile file;

// ====== Строка с именем файла

CString fn("MyFile.dat");

//===== Попытка открыть файл для чтения

if ( ! file.Open(fn,CFile::modeRead))

{

MessageBox ("He могу открыть файл "+fn, "Ошибка");

return;

}

Он должен писать код с учетом того, что файл может быть заблокирован какое-то время другим процессом. Если следовать уже рассмотренной тактике ожидания ресурса в течение какого-то времени, то надо создать код вида:

bool CMyWnd::TryOpen()

<

//====== Попытка открыть файл и внести изменения

CFile file;

CString fn("MyFile.dat"), Buffer;

//===== Флаг первой попытки

static bool bFirst = true;

if (file.Open (fn, CFile:: modeReadWrite I CFile::shareExclusive))

{

// Никакая другая программа не сможет открыть

// этот файл, пока мы с ним работаем

int nBytes = flie.Read(Buffer,MAX_BYTES);

//==== Работаем с данными из строки Buffer

//==== Изменяем их нужным нам образом

//==== Пришло время вновь сохранить данные

file.Write(Buffer, nBytes);

file. Close ();

//==== Начиная с этого момента, файл доступен

//==== для других процессов

//==== Если файл был открыт не с первой попытки,

//==== то выключаем таймер ожидания

if (IbFirst)

KillTimer(WAIT_ID);

//===== Возвращаем флаг успеха

return bFirst = true;

}

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

else

if (bFirst) // и эта неудача — первая,

//===== то запускаем таймер ожидания

SetTiraer(WAIT_ID, 1000, 0);

//===== Возвращаем флаг неудачи

return bFirst = false;

}

В другой функции, реагирующей на сообщения таймера, называемой, как вы знаете, функцией-обработчиком (Message Handler), надо предусмотреть ветвь для реализации выбранной тактики ожидания:



Содержание  Назад  Вперед