Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Возможно ли "зависание" в этом коде из VCL? (критические секции) [D6]


XP ©   (2005-02-21 17:27:00) 

Вот текст двух методов из класса 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 18:03:00) [1]

BiN ©   (21.02.05 17:53) [5]
в [2] приведена не та фраза


читаем как в [1]...


XP   (2005-02-21 17:56:00) [2]

Так то оно так, но следующий код вызовет возникновение исключительной ситуации, так как 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 17:53:00) [3]

пардон
в [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.
"


MBo   (2005-02-21 17:41:00) [4]

Правильно 1.
В занятую крит. секцию не может войти другой поток


GuAV   (2005-02-21 17:40:00) [5]

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:00) [6]

Если поток уже владеет критической секцией, ф-я сразу вернет управление


BiN   (2005-02-21 17:38:00) [7]

"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


Наверх

Титульная страница Поиск, карта сайта Написать письмо