• Dy1 (28.08.10 12:02) [0]
    Поток 1 отнимает почти всё время у потока 0. Подскажите пожалуйста что сделал не так.
    ...
     private
       ips: PList; // список указателей на запись пинга
       log: PStream;
       th1, th2: Tpotok;
       pause: cardinal;
       CritSect: _RTL_CRITICAL_SECTION;
       ThWork: boolean; // должен ли работать поток

       function NewPotok(const start_ind, inc_ind: cardinal): Tpotok;
     public
     end;
    ...
    implementation
    ...
    procedure WRlog(const text: ansistring);
    var
     s: ansistring;
     st: tsystemtime;
    begin
     windows.GetSystemTime(st);
     s := int2str(st.wSecond) + '.' + int2str(st.wMilliseconds) + #9 + text + #13#10;
     Form1.log.WriteAsync( s[1], Length(s));//иногда пишет непечатные символы. Обычно при работе потока 0
    end;
    //---
    procedure TForm1.TimerTimer(Sender: PObj);
    ...
    EnterCriticalSection(CritSect);
       if log.Busy Then log.Wait;
       log.Free;
       log := kol.NewWriteFileStream( GetStartDir + kol.Date2StrFmt('dd', Now) + '.txt');
    LeaveCriticalSection(CritSect);
     end;

     LV.Invalidate;
    end;
    //---
    procedure TForm1.KOLForm1Destroy(Sender: PObj);
    begin
     ThWork := False;

     if th2.Thread <> nil Then
     begin
       if th2.Thread.Suspended then th2.Thread.Resume;
       th2.Thread.WaitFor;
       th2.Thread.Free;
     end;

     if th1.Thread <> nil Then
     begin
       if th1.Thread.Suspended then th1.Thread.Resume;
       th1.Thread.WaitFor;
       th1.Thread.Free;
     end;
    end;
    //---
    procedure TForm1.KOLForm1FormCreate(Sender: PObj);
    begin
    ...
     if ips.Count = 1 Then  th1 := NewPotok(0, 0);
     if ips.Count > 1 Then
     begin
       th1 := NewPotok(0, 2); // с индекса 0 через 2
       th2 := NewPotok(1, 2);
     end;
    end;
    //===
    function TForm1.NewPotok(const start_ind, inc_ind: cardinal): Tpotok;//PThread
    begin
     Result.Thread := kol.NewThread;
     Result.Thread.OnExecute := Result.ThreadExecute;
     Result.Thread.Data := Pointer(start_ind);
     Result.Thread.Tag := inc_ind;
     Result.Thread.Resume;
    end;
    //-----
    function Tpotok.ThreadExecute(Sender: PThread): Integer;
    var
     i, c: cardinal;
    begin
     c := Form1.ips.Count;
     While Form1.ThWork do
     begin
       i := cardinal(Sender.Data);//начальное значение
       While(c > i)AND Form1.ThWork do
       begin
    WRlog('поток '+int2str( cardinal(Sender.Data) )+#9+pir(Form1.ips.Items[i])^.ip);
         i := i + Sender.Tag;
       end;//While c > i
    sleep(100);
     end;//While ThWork

     Result := 0;
    end;

  • Dy1 (28.08.10 12:10) [1]
  • Vladimir Kladov © (28.08.10 17:51) [2]
    1. WriteAsync предназначен для отложенной записи из главного потока. Для каждого обращения создается свой дополнительный поток с автозавершением. Если этот поток уже существует, выполняется простейшее ожидание существующего. При работе с одним и тем же объектом PStream из двух разных потоков не гарантируется, что не произойдет одновременное создание двух таких потоков, а дальше- как (не)повезет. Вывод: нужна защита вызова записи в поток данных, чтобы вызовы из разных нитей-потоков не мешали друг другу. Или секция, если защищается тот же кусок кода, или семафор.

    2. В KOL есть функция LogFileOutput. Для процедуры журналирования подходит лучше. Но защищать при вызове из разных нитей все равно надо, иначе файл не удастся открыть дважды, и облом гарантирован.
  • Dy1 (28.08.10 20:23) [3]
    спасибо. Попробую
Есть новые Нет новых   [120347   +17][b:0][p:0.004]