Критические секции
Модератор: Модераторы
Э... Это зависит от того, что ты понимаешь под словом все... На самом деле смысл критической секции прост, если кто-то вошёл, то все остальные при попытке входа - тормозят и ждут выхода.
По этому - что значит "одну на все"? В критическую секцию можно входить несколько раз, по этому создавать кажый раз новый объект нет необходимости. Чисто технически, можно использовать одну критическую секцию на всю программу, но это приведёт к лагам из-за возможного неоправдонного использования блокировок.
Критические секции рекомендуется создавать для переменной или группы переменных, с которыми идёт работа из нескольких нитей.
Допустим у нас есть переменные 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)
По этому - что значит "одну на все"? В критическую секцию можно входить несколько раз, по этому создавать кажый раз новый объект нет необходимости. Чисто технически, можно использовать одну критическую секцию на всю программу, но это приведёт к лагам из-за возможного неоправдонного использования блокировок.
Критические секции рекомендуется создавать для переменной или группы переменных, с которыми идёт работа из нескольких нитей.
Допустим у нас есть переменные 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)
Ну ты и выдал лекцию )))) Я знаю что такое критические секции
Вопрос о другом.
вместо переменых cs1 и cs2 я могу использовать одну перменную ? Т.е.:
Дело в том, что я совершенно не понимаю смысла перменной типа TRTLCriticalSection ...
Код: Выделить всё
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 ...
Переменная типа TRTLCriticalSection у программиста должна ассоциироваться с каким-нибудь ресурсом, над которым допустимо производить только атомарные (неделимые) операции. Сама переменная это своего рода псевдоним ресурса.
Например:
А:=Состояние счёта
А:=А+Вложение
Состояние счёта:=А
Это типичная атомарная операция. Если у вас в таблице хранится Состояние нескольких счетов, то можно для каждого сделать свою кр.секцию(1 вариант), или одну на всю таблицу(2 вариант). Если состояние счетов меняется часто, то более быстрым будет первый вариант, т.к. блокировки будут на уровне отдельных счетов, а не на уровне всей таблицы.
Например:
А:=Состояние счёта
А:=А+Вложение
Состояние счёта:=А
Это типичная атомарная операция. Если у вас в таблице хранится Состояние нескольких счетов, то можно для каждого сделать свою кр.секцию(1 вариант), или одну на всю таблицу(2 вариант). Если состояние счетов меняется часто, то более быстрым будет первый вариант, т.к. блокировки будут на уровне отдельных счетов, а не на уровне всей таблицы.
STAKANOV писал(а):Ну ты и выдал лекцию )))) Я знаю что такое критические секцииВопрос о другом.
Не могу ответить. Формально - можешь. А вот будет ли хуже... Надо знать как вызываются P1 и P2. Если P1 может параллельно работать одновременно только с P1, а P2 только с P2 - да. Если может быть P1 параллельно с P2 и они работают с разными данными, то не стоит.
Но опять же - где. На однопроцессорных компах разницы не будет. На SMP и многоядреных - будет.
STAKANOV писал(а):Дело в том, что я совершенно не понимаю смысла перменной типа TRTLCriticalSection ...
А я о чём писал? TRTLCriticalSection - хендл. Указатель на объект ядра. Никакой "внутренней структурой" с точки зрения паскаля не обладает.
- Иван Шихалев
- энтузиаст
- Сообщения: 1138
- Зарегистрирован: 15.05.2006 11:26:13
- Откуда: Екатеринбург
- Контактная информация:
-
Гость_PVOzerski
Гость_PVOzerski писал(а): Но это все-таки не хэндл. В RTL эта штука описана ка record. Начинка зависит от платформы.
Интересное кино, а что такое по твоему хендл? Или все остальные разработчики - састера мазохизма?
-
Гость_PVOzerski
Идентификатор, но не структура - даже если она - массив или запись, содержащая идентификаторы. Может ведь быть и массив хэндлов, и запись или объект с полями-хэндлами. А иначе можно было бы и имя файла хэндлом назвать 
Кстати, а можно ли назвать хэндлом указатель?
Особенно, если память виртуальная...
Кстати, а можно ли назвать хэндлом указатель?
