![]() |
AW: Multithreading und Globale Funktionen
Grundsätzlich musst Du die Aufrufe LockList/Unlocklist ein einem Resourcenschutzblock kapseln. Das geht so:
Delphi-Quellcode:
Natürlich hängt der zweite Thread im LockList. Nämlich genausolange, wie der erste Thread sein UnlockList noch nicht aufgerufen hat.
MyLocalList := TheThreadList.LockList;
Try DoSomethingWith(MyLocalList); Finally TheThreadList.UnlockList; End; Mit dem Aufruf von "Locklist" öffnet Du die Tür zur Liste, zieht aber den Schlüssel von der Tür ab und macht hinter dir wieder zu. "Unlocklist" verlässt die Liste, schließt wieder ab und hinterlässt den Schlüssel. Der Aufruf von "LockList" wartet so lange, bis der Schlüssel wieder in der Tür steckt. |
AW: Multithreading und Globale Funktionen
Hallo,
wenn im anderen Thread die List gesperrt ist (locked) dann kann der zweite Thread nicht darauf zugreifen. Also nur die List sperren wenn Du darauf zugreifen willst. Grüße Klaus |
AW: Multithreading und Globale Funktionen
So schaut mein Thread (gekürzt) aus:
Delphi-Quellcode:
Wenn der Thread nun das Locklist aufruft steht er!?
constructor TNames_thread.Create(const MainWindowHandle : Thandle);
begin inherited create(True); // CreateSuspended = true FMainHandle := MainWindowHandle; FreeOnTerminate := False; end; procedure TNames_thread.Execute(); var Msg : TMsg; List: TList; len : Integer; begin while (not Terminated) do begin List := All_Names.Locklist; try len := List.Count; finally All_Names.Unlocklist; end; Sleep(1000); end; // while (not Terminated) do Terminate; end; Das ist bei beiden Threads gleich. Der was geht hat ja die OnUDPRead vom UDP Server und diese Funktion wird von einem andern Thread (TIdUDPListenerThread) ausgeführt. Dann kann das Locklist durchgeführt werden. Die All_Names Liste wird in der Mainform in der OnCreate erzeugt. EDIT: Fehler gefunden! Ich habe in der OnCreate im MainThread zuerst ein All_Names.Locklist.clear ausgeführt. danach aber kein Unlock! Jetzt geht's! |
AW: Multithreading und Globale Funktionen
Jetzt habe ich noch eine Frage zu dem Thema, aber mit einer anderen Funktion:
Delphi-Quellcode:
Kann man sowas für Multithread verwenden? Oder wird da das Result zurückgesetzt wenn gerade ein Thread in der For Schleife ist und ein anderer die GetString ausführt?
function GetString(Data : TBytes):String;
var i : Integer; begin Result := ''; for i := 0 to High(Data) do Result := Result + IntToHex(Data[i], 2); end; Oder muss es dann so gemacht werden:
Delphi-Quellcode:
Ich will sozusagen einen Logger machen. Wenn ich nun CriticalSection verwende ist der eine Thread solange blockiert bis der andere Thread durch ist. Dies führt zu einer nicht gewollten Verzögerung wenn es jetzt um viele Daten geht.
function GetString(Data : TBytes):String;
var i : Integer; begin EnterCriticalSection(CS); try Result := ''; for i := 0 to High(Data) do Result := Result + IntToHex(Data[i], 2); finally LeaveCriticalSection(CS); end; end; |
AW: Multithreading und Globale Funktionen
Das kommt auf die Daten an. Wenn diese Daten von mehreren Threads verändert/gelesen werden, muß eine Synchronisation stattfinden, ansonsten nicht. Es gibt zT sehr clevere Ansätze um parallel an großen Datensätzen zu arbeiten ohne daß sich die Threads in die Quere kommen.
Eine Frage hier wäre bspw., ob sich "Data" (durch einen anderen Thread) ändert, während es von dieser Funktion verarbeitet wird. Ohne weitere Infos kann man da keine konkreten Aussagen machen. |
AW: Multithreading und Globale Funktionen
Ne, Data gehört zu jedem Thread selber der die Funktion aufruft.
D.h. jeder Thread ruft die Funktion auf mit seinen eigenen privat deklariertden Data mit unterschiedlicher länge. Ich bin mir halt nicht sicher, wenn sich schon ein Thread in der Funktion befindet das Result von einem anderen Thread wieder mit dem Result :=''; wieder zurückgesetzt wird. Oder hat jeder Aufruf sein eigenes Result? Oder ob dadurch das High(Data) auch verbogen wird? Lokale Variabeln gelten ja für jeden eigenen Aufruf/Thread selber. |
AW: Multithreading und Globale Funktionen
Zitat:
Zitat:
|
AW: Multithreading und Globale Funktionen
Ok, danke!
Dann werde ich das mal probieren und sehen ob es zu Exceptions kommt. Mit dem "verbiegen" des High(Data) hatte ich gemeint, wenn der erste Thread z.B. mit Data[len=500] aufruft. Der zweite dann mit Data[len=3000]. Wenn nun auch i beim ersten Thread bis 2999 raufgezählt wird, dann gibt's natürlich Probleme weil der erste ja nur bis 499 geht. |
AW: Multithreading und Globale Funktionen
Zitat:
|
AW: Multithreading und Globale Funktionen
Bremst weniger aus.
Delphi-Quellcode:
Wobei ich mich immer frage, wie man auf soeine "kranke" Schleife kommt, mit soeiner Masse an langsamen Stringoperationen. :shock:
function GetString(Data : TBytes):String;
var Temp: TBytes; i : Integer; begin EnterCriticalSection(CS); try Temp := Copy(Data) finally LeaveCriticalSection(CS); end; Result := ''; for i := 0 to High(Temp) do Result := Result + IntToHex(Temp[i], 2); end; > ![]() Abgesehn davon würde ich nicht den Data-Parameter auf dieser Seite absichern, sondern ich würde auf der aufrufenden Seite das absichern, welches man an Data übergibt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz