Мои Конспекты
Главная | Обратная связь

...

Автомобили
Астрономия
Биология
География
Дом и сад
Другие языки
Другое
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Металлургия
Механика
Образование
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Туризм
Физика
Философия
Финансы
Химия
Черчение
Экология
Экономика
Электроника

IfFBufInit then





Помощь в ✍️ написании работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Begin

WaitForSingleObject(FCriticalMutex, DefaultWaitTime);

FBufInit := false;

FBufSize := 0;

FreeMem(FBuf);

ReleaseSemaphore(FEntriesUsed, 1, nil);

ReleaseSemaphore(FEntriesFree, 1, nil);

CloseHandle(FEntriesFree);

CloseHandle(FEntriesUsed);

ReleaseMutex(FCriticalMutex);

CloseHandle(FCriticalMutex);

end;

end;

 

functionTBoundedBuffer.ControlledWait(Semaphore: THandle): boolean;

Var

ErrCode: integer;

 

Begin

Repeat

ErrCode := WaitForSingleObject(Semaphore, DefaultWaitTime);

if(ErrCode = WAIT_OBJECT_0) or(ErrCode = WAIT_ABANDONED) then

Begin

{ If wait abandoned, return failure. Buffer not properly

cleaned up }

result := ErrCode = WAIT_OBJECT_0;

exit;

end;

{ Wait timed out. Check whether buffer state initialised }

ifWaitForSingleObject(FCriticalMutex, DefaultWaitTime) <>

WAIT_OBJECT_0 then

Begin

result := false;

exit;

End

Else

Begin

result := FBufInit;

ReleaseMutex(FCriticalMutex);

end;

until notResult;

end;

 

functionTBoundedBuffer.PutItem(NewItem: Pointer): boolean;

 

{ Called by producer thread }

Var

NthItem: TBufferEntries;

 

Begin

result := false;

{ WAIT(EntriesFree) }

If notControlledWait(FEntriesFree) then

exit;

if(WaitForSingleObject(FCriticalMutex, DefaultWaitTime) <>

WAIT_OBJECT_0)

Or notFBufInit then

{ NB.This condition depends on L -> R lazy evaluation }

exit;

NthItem := FBuf;

Inc(NthItem, FWritePtr);

NthItem^ := NewItem;

FWritePtr := (FWritePtr + 1) modFBufSize;

ReleaseMutex(FCriticalMutex);

{ SIGNAL(EntriesUsed) }

ReleaseSemaphore(FEntriesUsed, 1, nil);

result := true;

end;

 

functionTBoundedBuffer.GetItem: Pointer;

 

{ Called by consumer thread }

 

Var

NthItem: TBufferEntries;

Begin

result := nil;

{ WAIT(EntriesUsed) }

If notControlledWait(FEntriesUsed) then

exit;

if(WaitForSingleObject(FCriticalMutex, DefaultWaitTime) <>

WAIT_OBJECT_0)

Or notFBufInit then

{ NB.This condition depends on L -> R lazy evaluation }

exit;

NthItem := FBuf;

Inc(NthItem, FReadPtr);

Result := NthItem^;

FReadPtr := (FReadPtr + 1) modFBufSize;

ReleaseMutex(FCriticalMutex);

{ SIGNAL(EntriesFree) }

ReleaseSemaphore(FEntriesFree, 1, nil);

end;

 

destructorTBoundedBuffer.Destroy;

Begin

ResetState;

inheritedDestroy;

end;

 

end.

Функции ожидания семафоров в нем были модифицированы, процедура очистки также претерпела некоторые изменения.

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

· WAIT_OBJECT_0 (Успех).

· WAIT_ABANDONED

· WAIT_TIMEOUT

Во-первых, если семафор освобожден, функция возвращает "успех", и никаких дальнейших действий не требуется... Во-вторых, в случае, когда функция Win32 WaitFor дает WAIT_ABANDONED, функция возвращает ошибку; это значение ошибки указывает, что поток завершается без корректного освобождения объекта синхронизации. Случай, который нам наиболее интересен - время ожидания истекло (WAIT_TIMEOUT). Это может быть по одной из двух возможных причин:

· Поток мог быть долгое время блокирован.

· Содержимое буфера было разрушено без уведомления соответствующего потока.

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

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

Доверь свою работу ✍️ кандидату наук!
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой



Поиск по сайту:







©2015-2020 mykonspekts.ru Все права принадлежат авторам размещенных материалов.