Как правильно передать строку в работающий поток?
 Добавлено: 18.06.2021 17:00:54
Добавлено: 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;
Но можно-ли так, и лучше-ли такой вариант?
Может есть другие способы?