Как правильно передать строку в работающий поток?
Добавлено: 18.06.2021 17:00:54
Есть поток с "бесконечным" циклом. На каждой итерации цикла, помимо основных действий, еще нужно проверять строку на наличие данных (то есть: fDataString.Length > 0) и обрабатывать эти данные, - которые должны попадать из главного потока.
Вопрос: обязательно использовать критические секции? Если - да, то как лучше?
Как я себе представляю это:
Меня тревожит момент (если не использовать критические секции): пока будет выполняться "Блок обработки внешних данных", то главный поток может успеть изменить fDataString вызовом SetDataString(S: string). В принципе, можно сделать:
Но можно-ли так, и лучше-ли такой вариант?
Может есть другие способы?
Вопрос: обязательно использовать критические секции? Если - да, то как лучше?
Как я себе представляю это:
- Код: Выделить всё
TMyThread = class(TThread)
private
fCS: TCriticalSection;
fDataString: string;
protected
procedure Execute; override;
public
procedure SetDataString(S: string);
constructor Create;
destructor Destroy; override;
end;
{...}
procedure TMyThread.Execute;
begin
while not Terminated do begin
{... any other do ...}
fCS.Enter; // Блок обработки внешних данных
if (fDataString.Length > 0) then begin
{... any do ...};
fDataString:= '';
end;
fCS.Leave;
{... any other do ...}
sleep(1);
end;
end;
procedure TMyThread.SetDataString(S: string);
begin
fCS.Enter;
fDataString:= S;
fCS.Leave;
end;
constructor TMyThread.Create;
begin
fCS:= TCriticalSection.Create;
inherited Create(false);
end;
destructor TMyThread.Destroy;
begin
FreeAndNil(fCS);
inherited Destroy;
end;
Меня тревожит момент (если не использовать критические секции): пока будет выполняться "Блок обработки внешних данных", то главный поток может успеть изменить fDataString вызовом SetDataString(S: string). В принципе, можно сделать:
- Код: Выделить всё
procedure TMyThread.Execute;
var
_s: string;
begin
while not Terminated do begin
{... any other do ...}
// BEGIN - Блок обработки внешних данных
_s:= fDataString;
fDataString:= '';
if (_s.Length > 0) then begin
{... any do ...};
end;
// END - Блок обработки внешних данных
{... any other do ...}
sleep(1);
end;
end;
Но можно-ли так, и лучше-ли такой вариант?
Может есть другие способы?