powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Проблема с потоками
19 сообщений из 19, страница 1 из 1
Проблема с потоками
    #39730799
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Программа парсит поступающие данные. Поставщик данных – TIdUDPServer с ThreadedEvent=true. Синхронизация через TIdNotify (вдруг это важно).

Обработка данных в однопоточном режиме выглядит так (выброшено всё не относящееся к сути проблемы):

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TfrmMain.ProcessSyslogMessage;
begin

TSyslogProgram(P_ProcedureSyslog);
inc(Core0Messages);
inc(MessagesCollected);

end;



На тестах обрабатывает ~15 000 входных данных в секунду, задействовано одно ядро, всё, в общем, хорошо. Но, естественно, не масштабируется.

Многопоточный вариант:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
procedure TfrmMain.ProcessSyslogMessage;
var i:integer;
begin

inc(IncomingMessages);
for i:=1 to High(CoreData) do
 if CoreData[i].CoreTH.Ready then
  begin
   CoreProcessMessage(i);
   Exit;
  end;

inc(DroppedMessages);

end;



Процедура вызова потока:

Код: pascal
1.
2.
3.
4.
procedure CoreProcessMessage(CoreIndex:integer);
begin
 CoreData[CoreIndex].CoreTH.Start.SetEvent;
end;



Поток:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
TCoreProcessMessageThread = class(TThread)
   private
    FStartEvent:TEvent;
    FCoreIndex:integer;
    FReady:boolean;
    FMessagesProcessed:longint;
   public
    property Start:TEvent read FStartEvent write FStartEvent;
    property CoreIndex:integer read FCoreIndex write FCoreIndex;
    property Ready:boolean read FReady write FReady;
    property MessagesProcessed:integer read FMessagesProcessed write FMessagesProcessed;
    constructor Create;
    destructor Destroy; override;
   protected
    procedure Execute; override;
   end;



Создание:

Код: pascal
1.
2.
3.
4.
5.
6.
constructor TCoreProcessMessageThread.Create;
begin
 inherited Create(false);
 FStartEvent:=TEvent.Create(nil,false,false,'');
 Resume;
end;



Выполнение (ждем Event, выполняем и опять ждем):

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
procedure TCoreProcessMessageThread.Execute;
begin
 while not Terminated do
  begin
   FReady:=true;
   FStartEvent.WaitFor(INFINITE);
   FReady:=false;
   inc(FMessagesProcessed);
   TSyslogProgram(CoreData[FCoreIndex].P_ProcedureSyslog);
  end;
end;



При инициализации программы создается пул потоков:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
type TCoreData=record
      CoreTH:TCoreProcessMessageThread;
      P_ProcedureSyslog:pointer;
     end;

var CoreData:array[1..4] of TCoreData;

for i:=1 to High(CoreData) do
  begin
   CoreData[i].CoreTH:=TCoreProcessMessageThread.Create;
   CoreData[i].CoreTH.FreeOnTerminate:=true;
   CoreData[i].CoreTH.CoreIndex:=i;
  end;



Вроде всё хорошо, потоки работают, но...(см. приложенное изображение)

Incoming=100000
Processed+Dropped=99852+76=99928

Куда-то пропадают сообщения. Независимо от скорости входных данных. Где я ошибаюсь?
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730808
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
flight-opГде я ошибаюсь?

В выборе UDP протокола.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730812
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимо. Однопоточный режим:
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730815
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Значит отлаживайся. Это и есть работа программиста.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730816
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
flight-opFReady:boolean;


Такое использование переменной для синхронизации является потенциальной ошибкой. Гипотетически возможна такая ситуация:

Поток 1 вызывает CoreData[CoreIndex].CoreTH.Start.SetEvent;
Поток 2 выходит из ожидания FStartEvent.WaitFor(INFINITE), и готовится выполнить FReady:=false;
Планировщик переключает обратно на поток 1
Выполняется код ProcessSyslogMessage и снова находится этот же самый CoreData c FReady=True, поскольку FReady:=false еще не был выполнен.
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730817
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, Дмитрий!
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730821
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aniskinflight-opFReady:boolean;


Такое использование переменной для синхронизации является потенциальной ошибкой. Гипотетически возможна такая ситуация:

Поток 1 вызывает CoreData[CoreIndex].CoreTH.Start.SetEvent;
Поток 2 выходит из ожидания FStartEvent.WaitFor(INFINITE), и готовится выполнить FReady:=false;
Планировщик переключает обратно на поток 1
Выполняется код ProcessSyslogMessage и снова находится этот же самый CoreData c FReady=True, поскольку FReady:=false еще не был выполнен.

(*Пытаюсь это представить*)
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730822
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно оставить переменную, но сделать FReady:=false перед CoreData[CoreIndex].CoreTH.Start.SetEvent;
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730824
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AniskinМожно оставить переменную, но сделать FReady:=false перед CoreData[CoreIndex].CoreTH.Start.SetEvent;

Спасибо, попробую.
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730826
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
С меня причитатеся :)
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730829
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
5% пропущенных, я бы так не радовался
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730834
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дегтярев Евгений5% пропущенных, я бы так не радовался

Да, и непонятно мне, по какой причине. Однопоточный вариант ест данных в 15 раз больше без дропов.
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730837
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
flight-opДа, и непонятно мне, по какой причине.Ты же сам добровольно делаешь дроп, если свободного потока нет. Не нужны дропы - жди, когда освободится какой нибудь поток и работай с ним.
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730839
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aniskinflight-opДа, и непонятно мне, по какой причине.Ты же сам добровольно делаешь дроп, если свободного потока нет. Не нужны дропы - жди, когда освободится какой нибудь поток и работай с ним.

Понимаешь, какая заковыка, предыдущая картинка - обработка 1000 сообщений в секунду.

А во эта - 10 000 сообщений в секунду.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TfrmMain.ProcessSyslogMessage;
begin
 if NoProcessing then Exit;
 inc(IncomingMessages);
 EmptySyslogData(SyslogData);
 TSyslogProgram(P_ProcedureSyslog);
 inc(Core0Messages);
end;



Что-то не так с определением свободного потока, но вот что...
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730843
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
flight-opЧто-то не так с определением свободного потокаС определением свободного потока все так. Просто его нет в момент запроса, это достаточно стандартная ситуация. Я вижу два варианта.

1) Простой вариант. Замени FReady: boolean на FReady: TEvent. В ProcessSyslogMessage вызывай WaitForMultipleObjects.

2) Вариант посложнее. В ProcessSyslogMessage ложи/клади сообщения во внутреннюю очередь, и пусть потоки сами читают из этой очереди.
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730845
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aniskinflight-opЧто-то не так с определением свободного потокаС определением свободного потока все так. Просто его нет в момент запроса, это достаточно стандартная ситуация. Я вижу два варианта.

1) Простой вариант. Замени FReady: boolean на FReady: TEvent. В ProcessSyslogMessage вызывай WaitForMultipleObjects.

2) Вариант посложнее. В ProcessSyslogMessage ложи/клади сообщения во внутреннюю очередь, и пусть потоки сами читают из этой очереди.

Попробую. Спасибо за помощь!
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730851
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Почесав в затылке, придумал 3-й способ - обработал дропы в главном потоке :)

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
procedure TfrmMain.ProcessSyslogMessage;
var i:integer;
begin
 if MultiCoreMessagesProcessing then
 for i:=1 to High(CoreData) do
  if CoreData[i].CoreTH.Ready then
   begin
    CoreProcessMessage(i);
    Exit;
   end;

 EmptySyslogData(SyslogData);

 if UseSyslogScript then TSyslogProgram(P_ProcedureSyslog) else ParseRawMessage(RawMessage,1,2,3,4,5,SysLogData);
 inc(Core0Messages);

 if DropMessage then
  begin
   DropMessage:=false;
   Exit;
  end;
 SyslogData.Text:=SyslogData.Text+' [Core:0]';
 PostSyslogMessage(SyslogData,SourceIP,RawMessage,DynamicVariablesArray);
end;
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730944
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
flight-opНа тестах обрабатывает ~15 000 входных данных в секунду, задействовано одно ядро, всё, в общем, хорошо. Но, естественно, не масштабируется.15к это очень плохо, вообще ни о чём для примитивного парсинга
хотя бы на два порядка надо больше

сколько выходит скорость если не парсить?
...
Рейтинг: 0 / 0
Проблема с потоками
    #39730950
flight-op
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kealon(Ruslan)15к это очень плохо, вообще ни о чём для примитивного парсинга
хотя бы на два порядка надо больше

сколько выходит скорость если не парсить?

Извини, вопрос лишен смысла. Софт для парсинга не парсить не может :))
15к - это потрошение _скриптом_ на одном ядре E3-1220 (вопросы хранения всей этой беды оставим за кадром). Скрин глянь :)
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Проблема с потоками
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]