Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Schreiben in eine zentrale Logdatei aus einem Thread heraus


Muck - Do 24.04.08 03:40
Titel: Schreiben in eine zentrale Logdatei aus einem Thread heraus
Hallo zusammen,

ich arbeite an einer Anwendung, die die 12 Cameras einer Bank in den Drive Thru Lanes ausliest und die Images speichert. Ja ja, die Security. Nun bisher habe ich noch nicht soviel mit Threads programmieren muessen.

Hier nun Details:
Der gleiche Thread laeuft 12 mal und liest ueber IDHTTP die Cameras aus.

Tritt hier ein Fehler in einer IDHTTP Exception auf, so will ich das in eine Logdatei schreiben.

Ist der Aufruf von TFileStream.write auf eine zentrale Varibale Thread Sicher? Hat da irgend jemand Erfahrung?

Hier ein Auszug aus dem Quelltext. Ich habe nur den fuer die Frage wichtigen Teil herauskopiert.
Es geht wie gesagt um den T.Write Befehl im Except innerhalb des Threads.
Der Thread laeuft bis zu 12 mal zur Zeit.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
  HttpThreadClass=class(TThread)
    private
      XCamNo:Integer;                    //What is my Camera Number
      QRead,QWrite:Byte;                 //Control for the command Q
      LP:Integer;                        // Last Position Number from POS Command
      LastPos:String;                    // Last Position Text
    protected
    procedure Execute; override;
    public
    procedure InitQ;
    procedure AddCommand(Value:String); {Add a Command line to the Thread Objects Q}
    function SomethingToDo:Boolean;     {is there still something in the Q}
    property CamNumber:Integer read XCamNo write XCamNo; // The channel number for every thread
  end;
  function InPortB(Port:DWord):Word; cdeclexternal 'ACCES32.dll';
  function InPort(Port:DWord):Word; cdeclexternal 'ACCES32.dll';
  function InPortL(Port:DWord):DWord; cdeclexternal 'ACCES32.dll';
var
HttpThread:Array[1..48of HttpThreadClass;
T:TFileStream; // The Logfile


procedure HttpThreadClass.Execute();
var S:String;FS:TFileStream;CamNo:Integer;idhttp1:TidHttp;RS,ImageStamp:String;X:TSystemTime;
begin
       CamNo:=XCamNo; // Thats my number
       idhttp1:=TIdHttp.Create;
       FS:=TFileStream.Create(RS,fmCreate or fmShareExclusive);
        try
          idhttp1.Request.BasicAuthentication:=true;
          idhttp1.Request.Username:=Cams[CamNo].Username;
          idhttp1.Request.Password:=Cams[CamNo].Password;
          idhttp1.MaxAuthRetries:=1;
          RS:=StringReplace(Cams[CamNo].GetCommand,'%P1',ImageStamp,[rfReplaceAll]);
          idHttp1.Get(RS,FS);
        except
          on e:Exception do begin
            RS:=e.message;
            FS.Write(RS[1],length(RS));
            T.Write(RS[1],length(RS));
          end;
        end;
        FS.Free;
        idhttp1.Free;
end;


Fuer Anregungen waere ich echt dankbar

Bis dann

Markus

Moderiert von user profile iconAXMD: Code- durch Delphi-Tags ersetzt


AXMD - Do 24.04.08 09:28

Du könntest das eventuell mit einer CritialSection lösen - nur so ein Gedanke, da ich mit Delphi schon etwas länger nichts mehr zu tun hatte.

AXMD


BenBE - Do 24.04.08 18:31
Titel: Re: Schreiben in eine zentrale Logdatei aus einem Thread her
user profile iconMuck hat folgendes geschrieben:
Ist der Aufruf von TFileStream.write auf eine zentrale Varibale Thread Sicher? Hat da irgend jemand Erfahrung?

Nope, ist nicht Thread-Safe, da Du die Reihenfolge für Datenblöcke, die an die Windows-API gereicht werden nicht garantieren kannst.

Kapsel am Besten deine Logging-Funktionalität in einer Klasse\Funktion und sichere wie AXMD gesagt hat, die eigentliche Schriboperation mit einer Critical Section ab, so dass Du garantieren kannst, dass die Verarbeitung der Schreib-Befehle in einer bestimmten Reihenfolge abläuft, ohne dass ein Schreibbefehl einen anderen unterbrechen knn; d.h. die Schreiboperationen atomar sind.