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

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

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

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

Сообщение serg_iv » 14.12.2006 10:26:46

Объясните пожалуйста как правильно испльзовать критические секции в коде.
Есть ли разница использования в винде и в линуксе?
serg_iv
постоялец
 
Сообщения: 276
Зарегистрирован: 15.10.2005 18:45:46
Откуда: Миасс

Сообщение Uniser » 26.12.2006 12:22:57

Код: Выделить всё
uses Windows;
var SEC1,SEC2 :TRTLCriticalSection;

эти переменные для программиста ассоциируются с ресурсами, которые необходимо блокировать. Блокировка возможна только для различных (конкурирующих) потоков одного процесса. Например: SEC1 может быть логически связан с таким ресурсом как
Код: Выделить всё
LS:TList
Если вы не хотите чтобы другой поток читал список (TList) во время модификации, то следует в начале модификации и в начале чтения списка вызвать
Код: Выделить всё
EnterCriticalSection(SEC1);
а в конце
Код: Выделить всё
LeaveCriticalSection(SEC1);
Естественно, вызвав перед чтением списка Enter... другой поток при попытке модификации обязан вызвать (это ложится на плечи программиста) Enter... при этом он уснёт до тех пор, когда первый поток после чтения списка вызовет Leave... И наоборот

Код: Выделить всё
// в начале программы
InitializeCriticalSection(SEC1); //Подготовка переменной SEC1
InitializeCriticalSection(SEC2);

EnterCriticalSection(SEC1); // Ресурс заблокирован
// С этого места поток может заснуть, если конкурирующий поток
// заблокировал ресурс раньше.

LeaveCriticalSection(SEC1); // Ресурс освобождён


// в конце программы
DeleteCriticalSection(SEC1); // Теперь можно завершать программу
DeleteCriticalSection(SEC2); // И нельзя использовать SEC1, SEC2

Случай мёртвой блокировки (dead lock) при которой несколько потоков виснут:
1. Поток1: Enter..(SEC1);
2. Поток2: Enter..(SEC2);
3. Поток1: Enter..(SEC2); 1-й засыпает т.к. 2-й уже вошёл в критическую секцию SEC2
4. Поток2: Enter..(SEC1); 2-й засыпает т.к. 1-й уже вошёл в критическую секцию SEC1 и оба никогда не проснутся.

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

Сообщение Uniser » 26.12.2006 12:25:31

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

Сообщение serg_iv » 26.12.2006 13:45:18

Спасибо, а то так и не доберусь до гугля.
serg_iv
постоялец
 
Сообщения: 276
Зарегистрирован: 15.10.2005 18:45:46
Откуда: Миасс


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

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

Сейчас этот форум просматривают: Google [Bot] и гости: 5

Рейтинг@Mail.ru