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
TCriticalSection
und wenn/da du dich mit der
WinAPI CreateThread nicht so auskennst (wenn ich mir TID anseh)
> schau dir mal
TThread 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.