Нужна параллельная непараллельность.

Страдалецъ
Дата: 14.08.2019 23:36:17
Вот такой выходит у меня лог работы 4 процессов.
1: Processor 9604 Idle
1: Processor 1248 Idle
1: Processor 8596 Idle
1: Collector Start
5: Processor 9604 Idle
5: Processor 1248 Idle
5: Processor 8596 Idle
5: Collector Busy
9: Processor 9604 Idle
9: Processor 1248 Idle
9: Processor 8596 Idle
12: Processor 9604 Idle
12: Collector Idle
12: Processor 1248 Busy
15: Collector Busy
16: Collector Idle
17: Collector Busy
18: Processor 1248 Idle
18: Processor 8596 Busy
20: Collector Idle
21: Collector Busy
22: Collector Idle
22: Processor 8596 Idle
22: Processor 9604 Busy
25: Collector Busy
26: Collector Idle
27: Collector Busy
28: Processor 9604 Idle
28: Processor 1248 Busy
30: Collector Idle
31: Processor 1248 Idle
31: Processor 8596 Busy
33: Processor 9604 Busy
33: Processor 8596 Idle
35: Processor 9604 Idle
35: Processor 1248 Idle
35: Collector Finale
Лог формируется в двух обработчиках событий этих процессов. И там все просто:
procedure TForm50.FileCollectorChangedState(Sender: TObject; State: TFileCollectorState);
begin
 case State of
   fcStart: Log.Lines.Add(Format('%d: Collector Start', [Log.Lines.Count+1]));
   fcIdle: Log.Lines.Add(Format('%d: Collector Idle', [Log.Lines.Count+1]));
   fcBusy: Log.Lines.Add(Format('%d: Collector Busy', [Log.Lines.Count+1]));
   fcFinale: Log.Lines.Add(Format('%d: Collector Finale', [Log.Lines.Count+1]));
 end;
end;

procedure TForm50.FileProcessorChangedState(Sender: TObject; State: TFileProcessorState);
begin
 case State of
   fpIdle: Log.Lines.Add(Format('%d: Processor %d Idle', [Log.Lines.Count+1, TFileProcessor(Sender).ThreadID]));
   fpBusy: Log.Lines.Add(Format('%d: Processor %d Busy', [Log.Lines.Count+1, TFileProcessor(Sender).ThreadID]));
 end;
end;

Работает все как надо... параллельно... но вот нумерация строк в логе не последовательная. И что делать? Заводить очередь сообщений в лог?
DimaBr
Дата: 14.08.2019 23:43:29
Использовать синхронизацию
Страдалецъ
Дата: 14.08.2019 23:49:03
В каком месте? При генерации событий в процессах?
X-Cite
Дата: 15.08.2019 00:07:04
Если очень надо в файл и он нужен один, то заводите диспетчер. Ваши процессы логируют в него, а он пишет и следит за нумерацией..
Страдалецъ
Дата: 15.08.2019 00:11:09
Ну да, действительно надо было сделать так:
procedure TFileProcessor.SetState(const Value: TFileProcessorState);
begin
 FState := Value;
 Synchronize(procedure begin if Assigned(FChangedStateEvent) then FChangedStateEvent(Self, FState); end);
end;

Теперь все выводит как надо.
1: Processor 9560 Idle
2: Processor 6368 Idle
3: Processor 9560 Idle
4: Processor 6368 Idle
5: Processor 9560 Idle
6: Collector Start
7: Processor 6368 Idle
8: Processor 9560 Idle
9: Collector Busy
10: Processor 6368 Idle
11: Processor 10576 Idle
12: Processor 9560 Idle
13: Processor 6368 Idle
14: Processor 10576 Idle
15: Collector Idle
16: Processor 9560 Busy
17: Collector Busy
18: Processor 9560 Idle
19: Processor 6368 Idle
20: Processor 10576 Idle
21: Processor 9560 Idle
22: Collector Idle
23: Processor 6368 Busy
24: Collector Busy
25: Processor 6368 Idle
26: Processor 10576 Idle
27: Processor 9560 Idle
28: Processor 6368 Idle
29: Collector Idle
30: Processor 10576 Busy
31: Collector Busy
32: Processor 10576 Idle
33: Processor 9560 Idle
34: Processor 6368 Idle
35: Processor 10576 Idle
36: Collector Idle
37: Processor 9560 Busy
38: Collector Busy
39: Processor 9560 Idle
40: Processor 6368 Idle
41: Processor 10576 Idle
42: Collector Idle
43: Processor 9560 Busy
44: Collector Busy
45: Processor 9560 Idle
46: Processor 10576 Idle
47: Processor 6368 Idle
48: Processor 9560 Idle
49: Collector Idle
50: Processor 10576 Busy
51: Collector Finale
52: Processor 6368 Idle
53: Processor 9560 Idle
54: Processor 10576 Idle
Страдалецъ
Дата: 15.08.2019 00:24:48
Нет, так неправильно. Я таким образом свел на нет работу потоков.
Страдалецъ
Дата: 15.08.2019 01:15:52
Нет, это я неправильно делаю. Нельзя использовать событие в потоке и потом его обрабатывать в основном приложении, смысл потока просто теряется, надо видимо через систему сообщений это делать.
Zelius
Дата: 15.08.2019 08:45:42
Страдалецъ
В каком месте? При генерации событий в процессах?

при использовании разделяемого ресурса
const
  StateNames: arrayy[TFileCollectorState] of string = ('fsStart', ...);

procedure TForm50.FileCollectorChangedState(Sender: TObject; State: TFileCollectorState);
begin
  CritSec.Enter;
  try
    Log.Lines.Add(Format('%d: Collector %s', [ Log.Lines.Count+1, StateNames[State]]));
  finally
    CritSec.Enter;
  end;
end;


Log - если это VCL объект из главного потока, то напрямую к нему добавлять строки из дополнительных потоков нельзя
Zelius
Дата: 15.08.2019 08:48:27
Zelius,

описка
  finally
    CritSec.Leave;
  end;
Василий 2
Дата: 15.08.2019 10:33:45
Если задача только в наращивании счетчика, то InterlockedIncrement. Доступ к файлу система сама разрулит