Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.171 Beiträge
 
Delphi 12 Athens
 
#2

Re: Variablenübergabe Createthread verständnisproblem

  Alt 19. Jan 2008, 22:06
1: Also erstmal ist dieser Dateizugriff nicht ThreadSave

Append öffnet eine Datei und setzt den Dateizeiger auf das Dateiende.
> wenn jetzt zwischen Append und WriteLn ein anderer Thread in die Datei was reingeschrieben hat, dann stimmt die Position nicht mehr, da sich das Dateiende verschiebt, aber der nicht Dateizeiger in f.

2: CreateThread übergibst du einen Zeiger auf den String "S"
gehtst dann weiter veränderst den String (für den nächsten Thread)
also könnte (und ist mit Sicherheit auch) sobald der Thread bei WriteLn ankommt der Zeiger ungültig.
> entweder ist in dem String ein anderer Inhalt (die nächste Zahl) oder noch schlimmer, der String steht inzwischen an einer anderen Speicheradresse und du greifst auf etwas zu, was kein String mehr sein muß.


Zitat von TheGame1492:
Ich möchte einfach 5 Zahlen/Strings in eine Datei (test.txt) schreiben, wobei jede Zahl/String durch einen eigenen Thread in diese Datei geschrieben werden soll.
warum?
bzw, was willst du mal erreichen...


Das Stringproblem kannst du aber leicht umgehn, indem du die Zahl übergibst und im Thread erst in einen String umwandelst.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  function WriteStringInFile( i: integer ):integer; stdcall;
  var
    s: String;
    f: textfile;
  begin
    s := IntToStr(i);
    {hier Dateizugriff für andere Threads sperren}
    AssignFile( f, 'test.txt' );
    {kannst aber auch erst hier sperren ... Assign öffnet die Datei ja noch nicht}
    Append(f);
    writeln( f, s ); // oder einfach nur writeln( f, i );
    CloseFile(f); // das wandelt dann sleber intern um
    {und hier Dateizugriff wieder freigeben}
  end;

var
  i: integer;
  TID: DWORD;
begin
  for i:=0 to 4 do
  begin
    CreateThread(nil, 0, @WriteStringInFile, i, 0, @tid);
    // tdi ist ein Ruckgabeparameter ... heißt, da schreibt ChreateThread was rein
    // und du kannst das auslesen (es wird also nichts an ChreateThread übergeben)
  end;
end;
außerdem muß du den Zugriff auf die Datei noch irgendwie ThreadSicher machen ... z.B. über eine Delphi-Referenz durchsuchenTCriticalSection

und wenn/da du dich mit der WinAPI CreateThread nicht so auskennst (wenn ich mir TID anseh)
> schau dir mal Delphi-Referenz durchsuchenTThread an, das hat dann auch schon einige nette Dinge zur ThreadSynchronisierung eingebaut.




PS: außerdem setzt ChreateThread nicht IsMultithreaded auf True
und wenn IsMultithreaded auf False steht, dann ist der speicherManager ebenfalls nicht ThreadSave und es könnte noch weitere Probleme geben.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat