AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Reicht Syncronize oder besser Syncronize + CriticalSection ?
Thema durchsuchen
Ansicht
Themen-Optionen

Reicht Syncronize oder besser Syncronize + CriticalSection ?

Ein Thema von DataCool · begonnen am 11. Aug 2004 · letzter Beitrag vom 27. Mär 2006
Antwort Antwort
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#1

Reicht Syncronize oder besser Syncronize + CriticalSection ?

  Alt 11. Aug 2004, 13:21
Hi Leute,

ich habe einen Indy TCP Server, der ja jede Connection in einem Thread verwaltet.
Jetzt lese ich die Daten vom Client und möchte diese in eine Textdatei schreiben.
Reicht es das schreiben durch den Aufruf mit Syncronize zu schützen ?
Oder das ganze ohne syncronize dafür mit CriticalSection ?
Oder beides zusammen ?
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Reicht Syncronize oder besser Syncronize + CriticalSecti

  Alt 11. Aug 2004, 13:31
Entweder ein von beiden. Beides zusammen ist Quatsch.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#3

Re: Reicht Syncronize oder besser Syncronize + CriticalSecti

  Alt 11. Aug 2004, 13:42
@Luckie:

Was würdest Du machen ? Also der Server erhält ähnlich wie bei einem Chat in kurzen Abständen viele Nachrichten und hat meistens 3-5 Connections simultan.
Jetzt will ich halt alles mit loggen und in ne Datei schreiben und als Schutzmechanismus halt etwas Verwenden das am wenigsten Ressoucen verbraucht und am schnellsten ist.
Ich tendiere zur CritialSection, weil dann wirklich nur das Schreiben schützen muss, bei Syncronize wird das ganze ja dann aus dem Main-Thread aufgerufen.
Sollte also langsamer sein, sehe ich das richtig ?
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Reicht Syncronize oder besser Syncronize + CriticalSecti

  Alt 11. Aug 2004, 13:45
Kann ich nicht beurteilen, was langsamer ist. Und ob CS oder Synchronize ist geschmackssache.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Vjay

Registriert seit: 2. Dez 2003
Ort: Berlin/Eschede
481 Beiträge
 
Delphi 7 Professional
 
#5

Re: Reicht Syncronize oder besser Syncronize + CriticalSecti

  Alt 11. Aug 2004, 13:46
Öffne die Datei im Hauptthread
Starte den TCP-Server

Vor jedem Zugriff dann Lock.Acquire und danach wieder freigeben. Ist schnellste und beste Methode, da dein Hauptthread nicht belastet wird. Und wenn dieser mal ausgelastet sein sollte funktioniert das Schreiben dennoch.
Wer später bremst ist eher tot.
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Reicht Syncronize oder besser Syncronize + CriticalSecti

  Alt 11. Aug 2004, 13:47
Critical Section in diesem Fall. Und die Logs dann direkt in die Datei via Append-Modus schreiben. Das ist am schnellsten.

Vermutung: CS ist nicht einmal nötig, da HDD Zugriffe eh synchronisiert sind

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#7

Re: Reicht Syncronize oder besser Syncronize + CriticalSecti

  Alt 11. Aug 2004, 13:49
Danke schön, an alle fähigen Gehirne hier
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Meta777

Registriert seit: 8. Sep 2004
Ort: Magdeburg
248 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

Re: Reicht Syncronize oder besser Syncronize + CriticalSecti

  Alt 27. Mär 2006, 22:31
Hi DPler,

Ich habe ein ähnliches Problem.
Ich habe eine Log-Klasse welche auch threadsicher FTP aktionen loggen soll.
Die Klasse wird aber auch in diversen anderen Programmen benutzt.
Das scheint auch ganz gut zu funktionieren aber manchmal bekomme ich AVs
und ich weiß nicht genau ob es nun an der Klasse liegt?
Ich habe den verdacht das es evtl. Probleme mit Synchronize und
Dateizugriffen gibt? Oder ist das TIdSync, von dem TLog abgeleitet ist,
nicht die optimale Wahl?
Das der Logeintrag auch an das Memo des Protokoll-Forms angehängt wird
sollte doch durch Synchronize kein Problem sein, oder?

Ein Logeintrag wird über die Klassenproceduren TLog.Add() hinzugefügt.

Bin für generelle oder konkrete Hinweise dankbar.

Gottes Segen

Nun etwas Source:
Delphi-Quellcode:
type
  TDaPrtData = record
    Typ: TDaPrtMsgType;
    Msg: String;
    Cls: ShortString;
    Code: Integer;
    SQL: String;
    Details: String;
    DoId: Integer;
    ConfigId: Integer;
  end;

//This is based on the example found in the indy newsgroup
  TLog = class(TIdSync)
  protected
    FPrtData: TDaPrtData;
    procedure DoSynchronize; override;
    constructor Create(const APrtData: TDaPrtData);
  public
    class procedure Add(const APrtData: TDaPrtData); overload;
    class procedure Add(const AStr: String); overload;
  end;




//---------------------------------------------------//
//------------------------ TLog ---------------------//

constructor TLog.Create(const APrtData: TDaPrtData);
begin
  FPrtData := APrtData;
  inherited Create;
end;

procedure TLog.DoSynchronize;
var
  lFileStream: TFileStream;
  lMode: Word;
  lString: String;

  procedure TruncateStream;
  var
    Buffer: TMemoryStream;
    c, n1, n2, Len: Int64;
  begin
// QueryPerformanceFrequency(c);
// QueryPerformanceCounter(n1);
    Buffer := TMemoryStream.Create;
    try
      Buffer.Size := konPrtLowFileSize;
      lFileStream.Position := lFileStream.Position - konPrtLowFileSize;
      Len := Buffer.CopyFrom(lFileStream, konPrtLowFileSize);
      Buffer.Position := 0;
      lFileStream.Position := 0;
//TODO 1: Alternative. Works but sure slow??
      lFileStream.Size := 0;
      lFileStream.Size := konPrtLowFileSize;

      lFileStream.Position := 0;
      lFileStream.CopyFrom(Buffer, Len);
      QueryPerformanceCounter(n2);
      OutputDebugString(PChar(FloatToStr(n2-n1/c, formatSet)));
// TLog.Add(FloatToStr(n2-n1/c, formatSet));//geht nicht - AV!?!¿!?
    finally
      Buffer.Free;
    end;
  end;

  procedure LogToScreen;
  begin
    try
      frmProt.memLog.Lines.BeginUpdate;
      if frmProt.memLog.Lines.Count > frmProt.PrtOptions.PrtSize then begin
        while frmProt.memLog.Lines.Count > frmProt.PrtOptions.PrtSize-50 do//Cut off 50 Lines
          frmProt.memLog.Lines.Delete(0);
        frmProt.memLog.Lines.Add('$$$'+konPrtColDel+DateTimeToStr(Now, formatSet)+'LOG TRUNCATE'+konPrtLineDel);
      end;
      frmProt.memLog.Lines.Add(lString);
// if True{Optionen_Form.miscAutoScrollLog }then begin
        frmProt.memLog.Perform(EM_LINESCROLL, 0, frmProt.memLog.Lines.Count);
// end;
      frmProt.memLog.Lines.EndUpdate;
    except
      frmProt.PrtOptions.AbledPrtModes := frmProt.PrtOptions.AbledPrtModes -
        [pmScreen];
    end;
  end;//procedure LogToScreen

  procedure LogToFile;
  begin
    try
      if FileExists(frmProt.PrtOptions.PrtFileName) then
        lMode := fmOpenReadWrite or fmShareDenyWrite
      else
        lMode := fmCreate;
      lFileStream := TFileStream.Create(frmProt.PrtOptions.PrtFileName, lMode);
      try
        if lMode <> fmCreate then
          lFileStream.Seek(0, soFromEnd);
        lFileStream.Write(LString[1], Length(lString));
        lFileStream.Write(sLineBreak, Length(sLineBreak)); // <-- sLineBreak is defined by VCL
        if lFileStream.Size > konPrtHighFileSize then begin
          TruncateStream;
        end;
      finally
        lFileStream.Free;
      end;
    except
      frmProt.PrtOptions.AbledPrtModes := frmProt.PrtOptions.AbledPrtModes -
        [pmFile];
    end
  end;//procedure LogToFile
begin
  lString := '';
  case FPrtData.Typ of
    pmtInformation: lString := '###' + konPrtColDel;
    pmtConfirmation: lString := '???' + konPrtColDel;
    pmtWarning: lString := 'x!x' + konPrtColDel;
    pmtError: lString := 'XXX' + konPrtColDel;
  end;
                       //Using a formatSetting var it is thread save.
  lString := lString + DateTimeToStr(Now, formatSet) + konPrtColDel +
    FPrtData.Msg + konPrtColDel + FPrtData.Cls + konPrtColDel + FPrtData.SQL + konPrtColDel +
    FPrtData.Details + konPrtColDel + IntToStr(FPrtData.DoId) + konPrtColDel +
    IntToStr(FPrtData.ConfigId) +
    konPrtLineDel;//2006_01_29 We need a Line-Delimiter cause of multiline prt entries!
  case frmProt.PrtOptions.PrtUsage of
    cbChecked: begin
      if pmScreen in frmProt.PrtOptions.AbledPrtModes then
        LogToScreen;
      if pmFile in frmProt.PrtOptions.AbledPrtModes then
        LogToFile;
    end;
    cbGrayed: begin
      if pmScreen in frmProt.PrtOptions.AbledPrtModes then
        LogToScreen;
    end;
    cbUnchecked:;//nothing
  end;//case cbUseProt.State
end;

class procedure TLog.Add(const APrtData: TDaPrtData);
begin
  with TLog.Create(APrtData) do try
    Synchronize;
  finally
    Free;
  end;
end;

class procedure TLog.Add(const AStr: String);
var
  LPrtData: TDaPrtData;
begin
  FillChar(LPrtData, SizeOf(LPrtData), #0);
  LPrtData.Msg := AStr;
  with TLog.Create(LPrtData) do try
    Synchronize;
  finally
    Free;
  end;
end;

//------------------------ TLog ---------------------//
//---------------------------------------------------//
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz