Главная страница
    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.46 MB
Время: 0.031 c
14-1108621820
stud
2005-02-17 09:30
2005.03.06
книги в формате pdf


3-1107857897
dreamse
2005-02-08 13:18
2005.03.06
проблема с сохранением базы


4-1106388517
Goorus
2005-01-22 13:08
2005.03.06
Подсказка к CheckBox


14-1108002944
Думкин
2005-02-10 05:35
2005.03.06
С Днем рождения! 10 февраля


1-1109019848
suharew
2005-02-22 00:04
2005.03.06
Как переименовать папку





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский