Форум: "Основная";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];
ВнизВозможно ли "зависание" в этом коде из VCL? (критические секции) Найти похожие ветки
← →
XP (2005-02-21 17:27) [0]Вот текст двух методов из класса TCanvas:
procedure TCanvas.Lock;
begin
EnterCriticalSection(CounterLock);
Inc(FLockCount);
LeaveCriticalSection(CounterLock);
EnterCriticalSection(FLock);
end;
function TCanvas.TryLock: Boolean;
begin
EnterCriticalSection(CounterLock);
try
Result := FLockCount = 0;
if Result then Lock;
finally
LeaveCriticalSection(CounterLock);
end;
end;
Если расписать, то получится следующая картина:function TCanvas.TryLock: Boolean;
EnterCriticalSection(CounterLock); // (1)
try
Result := FLockCount = 0;
if Result then
begin // вставлено из метода Lock
EnterCriticalSection(CounterLock); // (2)
Inc(FLockCount);
LeaveCriticalSection(CounterLock);
EnterCriticalSection(FLock);
end; // конец вставки
finally
LeaveCriticalSection(CounterLock);
end;
Если мне не изменяет зрение и логика, в строке, помеченной (2), произойдет зависание при попытке входа в критическую секцию, в которую уже зашли в строке (1), то бишь, так называемый BottleNick - сами же себя застопорили.
Но так реализовано у Borland"а.
В чем тут подвох?
Или я неправильно понимаю идеологию критических секций?
Кто подскажет, где правильная формулировка:
1. Критическая секция не позволяет двум потокам войти одновременно (EnterCriticalSection).
2. Критическая секция не позволяет кому угодно и как угодно войти дважды (EnterCriticalSection).
← →
BiN © (2005-02-21 17:38) [1]"EnterCriticalSection
The EnterCriticalSection function waits for ownership of the specified critical section object. The function returns when the calling thread is granted ownership.
" (c) msdn
← →
GuAV © (2005-02-21 17:40) [2]1.
из MSDN
EnterCriticalSection
...
Remarks
...
After a thread has ownership of a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section that it already owns.
← →
BiN © (2005-02-21 17:40) [3]Если поток уже владеет критической секцией, ф-я сразу вернет управление
← →
MBo © (2005-02-21 17:41) [4]Правильно 1.
В занятую крит. секцию не может войти другой поток
← →
BiN © (2005-02-21 17:53) [5]пардон
в [2] приведена не та фраза
Вот верный вариант:
"After a thread has ownership of a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section that it already owns.
"
← →
XP (2005-02-21 17:56) [6]Так то оно так, но следующий код вызовет возникновение исключительной ситуации, так как Operation2 не сможет получить эксклюзивный доступ к Canvas, ибо FLockCount > 0 (см. код в вопросе):
procedure TMyControl.Operation1;
begin
if Canvas.TryLock then
begin
...
Operation2;
...
end;
end;
procedure TMyControl.Operation2;
begin
if Canvas.TryLock then
...
else
raise Exception.Create("Wait until operation complete.");
end;
И это в контексте одного потока.
Вроде бы ничто не мешает получить доступ к Canvas (в Operation2), но Borland эту возможность блокирует при помощи FLockCount. Вместе с тем, использование Lock вместо TryLock даст, согласно msdn, требуемый результат.
Зачем так реализовано? Должен же быть в этом смысл?
← →
BiN © (2005-02-21 18:03) [7]BiN © (21.02.05 17:53) [5]
в [2] приведена не та фраза
читаем как в [1]...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.072 c