Критические секции

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Сообщение STAKANOV » 24.10.2005 12:59:10

В процедурах для работы с критическими секциями используется перемнная типа TRTLCriticalSection. А она должна быть определена для каждой критической секции или можно использовать одну на все?

С учетом смылса критической секции последнее кажется вполне логичным. :unsure:
Аватара пользователя
STAKANOV
энтузиаст
 
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение pda » 27.10.2005 02:21:54

Э... Это зависит от того, что ты понимаешь под словом все... На самом деле смысл критической секции прост, если кто-то вошёл, то все остальные при попытке входа - тормозят и ждут выхода.

По этому - что значит "одну на все"? В критическую секцию можно входить несколько раз, по этому создавать кажый раз новый объект нет необходимости. Чисто технически, можно использовать одну критическую секцию на всю программу, но это приведёт к лагам из-за возможного неоправдонного использования блокировок.

Критические секции рекомендуется создавать для переменной или группы переменных, с которыми идёт работа из нескольких нитей.

Допустим у нас есть переменные A, B, C и D. Мы работаем одновременно из нескольких нитей с A, B и C, D. При этом, пары A-B и C-D обрабатываются независимо друг от друга. В этом случае нам желательно создать две критические секции C1 и C2, которые будут защищать данные пар A-B и C-D соответсвенно.

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

Если таких мест в программе несколько, то вопрос порядка входа становится важным. Может возникнуть ситуация, назвваемая бесконечной блокировкой (дедлок, deadlock). Когда одна нить вошла в критическую секцию C2 и теперь пытается войти в C1, а другая вошла в C1 и теперь хочет войти в C2. Естественно, в этом случае программа останется блокированной навечно.

В этом случае решением является раз и навсегда определить порядок входа в критические секции. В более сложном виде это выглядит так: допустим у нас есть три критические секции A, B и C.

Если мы хотим работать только с данными, которые защищает A, B или С, то мы просто входим в соответсвующую критическую секцию и выходим по завершению.

Но если мы захотим использовать все данные, то мы должны входить в критические секции в выбранном порядке, здесь - по алфавиту:
A
B
C

Выход осуществляется в обратном порядке:

C
B
A

Если нам нужны данные только С и В, то мы входим только в порядке:

B
C

даже, если с B нам надо работать совсем немного и в самой глубине кода, работающего с C.

В общем случае, рекомендуется по возможности сокращать время, проводимое программой в критических секциях.

B)
Аватара пользователя
pda
постоялец
 
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение STAKANOV » 27.10.2005 14:10:10

Ну ты и выдал лекцию )))) Я знаю что такое критические секции ;) Вопрос о другом.
Код: Выделить всё
var
cs1,cs2:TRTLCriticalSection;
...
procedure P1;
begin
 EnterCriticalSection(cs1);
 ..
 LeaveCriticalSection(cs1);
end;

procedure P2;
begin
 EnterCriticalSection(cs2);
 ..
 LeaveCriticalSection(cs2);
end;

begin
InitCriticalSection(cs1);
InitCriticalSection(cs2);
...
DoneCriticalSection(cs1);
DoneCriticalSection(cs2);
end.


вместо переменых cs1 и cs2 я могу использовать одну перменную ? Т.е.:
Код: Выделить всё
var
cs:TRTLCriticalSection;
...
procedure P1;
begin
 EnterCriticalSection(cs);
 ..
 LeaveCriticalSection(cs);
end;

procedure P2;
begin
 EnterCriticalSection(cs);
 ..
 LeaveCriticalSection(cs);
end;

begin
InitCriticalSection(cs);
...
DoneCriticalSection(cs);
end.

Дело в том, что я совершенно не понимаю смысла перменной типа TRTLCriticalSection ...
Аватара пользователя
STAKANOV
энтузиаст
 
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение Uniser » 27.10.2005 23:21:40

Переменная типа TRTLCriticalSection у программиста должна ассоциироваться с каким-нибудь ресурсом, над которым допустимо производить только атомарные (неделимые) операции. Сама переменная это своего рода псевдоним ресурса.

Например:
А:=Состояние счёта
А:=А+Вложение
Состояние счёта:=А

Это типичная атомарная операция. Если у вас в таблице хранится Состояние нескольких счетов, то можно для каждого сделать свою кр.секцию(1 вариант), или одну на всю таблицу(2 вариант). Если состояние счетов меняется часто, то более быстрым будет первый вариант, т.к. блокировки будут на уровне отдельных счетов, а не на уровне всей таблицы.
Uniser
новенький
 
Сообщения: 46
Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава

Сообщение Uniser » 27.10.2005 23:24:11

В СУБД обычно реализованы оба варианта и они "видят" друг друга, т.е, если идёт блокировка всей таблицы, то блокировка одной записи будет ждать и наоборот.

И важно! Выходить из критических секций следует в обратном вхождению порядке.
Uniser
новенький
 
Сообщения: 46
Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава

Сообщение pda » 02.11.2005 19:40:49

STAKANOV писал(а):Ну ты и выдал лекцию )))) Я знаю что такое критические секции  ;) Вопрос о другом.

Не могу ответить. Формально - можешь. А вот будет ли хуже... Надо знать как вызываются P1 и P2. Если P1 может параллельно работать одновременно только с P1, а P2 только с P2 - да. Если может быть P1 параллельно с P2 и они работают с разными данными, то не стоит.

Но опять же - где. На однопроцессорных компах разницы не будет. На SMP и многоядреных - будет.

STAKANOV писал(а):Дело в том, что я совершенно не понимаю смысла перменной типа TRTLCriticalSection ...

А я о чём писал? TRTLCriticalSection - хендл. Указатель на объект ядра. Никакой "внутренней структурой" с точки зрения паскаля не обладает.
Аватара пользователя
pda
постоялец
 
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение Иван Шихалев » 04.11.2005 01:19:59

Народ, а не слабо :D по критическим секциям статью написать?
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Сообщение Гость_PVOzerski » 04.11.2005 19:32:33

Но это все-таки не хэндл. В RTL эта штука описана ка record. Начинка зависит от платформы.
Гость_PVOzerski
 

Сообщение pda » 05.11.2005 19:24:46

Гость_PVOzerski писал(а): Но это все-таки не хэндл. В RTL эта штука описана ка record. Начинка зависит от платформы.

Интересное кино, а что такое по твоему хендл? Или все остальные разработчики - састера мазохизма? :D В 90% случаев хендл - указатель на структуру ядра, используемую самим ядром, для обработки объекта. B)
Аватара пользователя
pda
постоялец
 
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение PVOzerski » 06.11.2005 18:04:26

Дык ведь указатель (или просто некий численный идентификатор), а не сама структура...
PVOzerski
постоялец
 
Сообщения: 109
Зарегистрирован: 19.05.2005 13:45:10
Откуда: СПб

Сообщение pda » 06.11.2005 23:14:06

PVOzerski писал(а): Дык ведь указатель (или просто некий численный идентификатор), а не сама структура...

Дык, ты говоришь - "не хендл". Тогда я и спрашиваю - что по твоему имеет право считаться хендлом?
Аватара пользователя
pda
постоялец
 
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение Гость_PVOzerski » 07.11.2005 14:50:55

Идентификатор, но не структура - даже если она - массив или запись, содержащая идентификаторы. Может ведь быть и массив хэндлов, и запись или объект с полями-хэндлами. А иначе можно было бы и имя файла хэндлом назвать :)

Кстати, а можно ли назвать хэндлом указатель? ;) Особенно, если память виртуальная...
Гость_PVOzerski
 


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 74

Рейтинг@Mail.ru