Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-1108810602
deramse
2005-02-19 13:56
2005.03.06
Как скопировать чётные символы строки в переменную ?


1-1108640063
_iceman_
2005-02-17 14:34
2005.03.06
Delphi 2005


1-1108541537
Neznaika
2005-02-16 11:12
2005.03.06
StayOnTop


1-1109056820
Hadroran
2005-02-22 10:20
2005.03.06
Чтение генератора из InterBase


1-1108988485
ASH
2005-02-21 15:21
2005.03.06
RTTI + DLL





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский