Цитата:
Сообщение от Zubastic
А можно пример? Как я понял, имеется ввиду CriticalSection, нет?
|
Да, это и есть блокировки (enter / leave или lock / unlock).
Пример (что первым попалось в коде). Есть поток, отвечающий за связь с веб-сервером (класс TWebClient). Если рабочий поток, собирающий данные. Рабочий поток для отправки данных вызывает метод AddUserData.
Код:
procedure TWebClient.AddUserData(Line: string);
begin
UserData.Lock;
try
UserData.Add(line);
finally
UserData.Unlock;
end;
end;
UserData - private свойство класса TWebClient.
Поток TWebClient с определенным интервалом соединяется с сервером и вызывает свой метод SendUserData:
Код:
function TWebClient.SendUserData: Integer;
var
SL: TStringList;
begin
SL := TStringList.Create;
try
SL.Clear;
UserData.Lock; // Блокируем объект
try
SL.AddStrings(UserData); // Копируем содержимое в локальный объект
UserData.Clear;
finally
UserData.Unlock; // Снимаем блокировку
end;
if SL.Count > 0 then
begin
Result := UploadData(SL);
if Result = -1 then
begin
UserData.Lock;
try
UserData.AddStrings(SL);
finally
UserData.Unlock;
end;
end;
end
else Result := 0;
finally
FreeAndNil(SL);
end;
end;
Общие данные - объект UserData (свой класс TSafeStringList). При работе с ним используются критические секции (сначала Lock, потом Unlock).
Код:
TSafeStringList = class(TStringList)
private
CriticalSection: TCriticalSection;
public
procedure Lock;
procedure Unlock;
constructor Create;
destructor Destroy; override;
end;
...
constructor TSafeStringList.Create;
begin
inherited Create;
CriticalSection := TCriticalSection.Create;
end;
destructor TSafeStringList.Destroy;
begin
CriticalSection.Free;
inherited Destroy;
end;
procedure TSafeStringList.Lock;
begin
CriticalSection.Enter;
end;
procedure TSafeStringList.Unlock;
begin
CriticalSection.Leave;
end;