Frage zu TCriticalSection;
-
Hallo,
ich habe einen Thread programmiert.
diesen erzeuge ich mit:// thread erzeugen cMailThread * Thread = new cMailThread(true); // thread konfigurieren Thread->ProgressBar = ProgressBar1; Thread->setConfiguration(ConfigList); Thread->FilenameLabel = lFileValue; Thread->EmailNrLabel = lMailNrValue; Thread->Counter = lCountMailsValue; Thread->mailsgesamt = lCountMailsValue->Caption.ToInt(); Thread->IdAntiFreeze = IdAntiFreeze; // OnTerminateEvent setzten Thread->OnTerminate = ThreadDone; fMain->ThreadsRunning ++; ThreadsRunning ++; // thread starten Thread->Resume(); Application->ProcessMessages();der Thread hat ein TCriticalSection Property:
class cMailThread : public TThread { private: TCriticalSection * Gate; ... public: TIdPOP3 * NMPOP3; ...In den Thread Methoden sperre andere Threads pauschal immer mit
Gate->Acquire();und gebe sie am Ende mit
ate->Release();wieder frei.
Beispiel:// Verbindungsdaten und grundeinstellungen setztn. __fastcall cMailThread::setPop3() { Gate->Acquire(); NMPOP3->ASCIIFilter = true; NMPOP3->Username = getListValue("USERID", ConfigList); NMPOP3->Password = getListValue("PASSWORD", ConfigList); NMPOP3->Host = getListValue("HOST", ConfigList); //NMPOP3->Port = getListValue("PORT", ConfigList).ToInt(); if (getListValue("DELETEMAIL", ConfigList).operator ==("true")) deleteMail = true; else deleteMail = false; FileExtension = "." + getListValue("FILEEXTENSION", ConfigList); Gate->Release(); }Alle Änderungen die der Thread in einem TFrame vornimmt, werden durch eine Funktion mit Synchronize() aufgerufen.
Nach meinem Verständnis sollte der Thread jetzt eingentlich Threadsicher sein.
Trotz alledem bekomme ich sobald mehr als ein Thread läüft massenweise Exceptions:Zu wenig Arbeitsspeicher
Daher zwei Fragen:
1. Habe ich beim "Threadsicher machen" etwas falsch gemacht?
2. Ist es sinnvoll die Methoden durch ein KLassenobjeckt von TCriticalSection zu sperren, oder muss das TCriticalSection Objeckt jeweils in der Methode in der es verwendet wird erzeugt und gelöscht werden?Danke!
P.s. Sorry für die verwirrende Namensgebung von NMPOP3. Das Objekt ist ein Objeckt der Klasse TIdPOP3.
-
niemand? Schade

Ab wann wird denn die Suchfunktion voraussichtlich wieder funktionieren?
-
Hab ich hier schon mal nach gesucht. Da gibt es nix aufschlussreiches...
-
Da ich a) das Problem nicht ganz verstanden habe und mich auch b) grade nicht damit beschäftigen kann vielleicht folgender Hinweis:
Synchronize sorgt automatisch für Thread-Sicherheit.
Thread-Sicherheit wird dann benötigt, wenn zwei Threads gleichzeitig parallel laufen und beide auf gemeinsame Daten zugreifen.
Um eine Threadsicherheit zu erstellen ist es dann nötig, das Schreiben und das Lesen und nur das Schreiben und das Lesen des Speicherbereichs z.B. mit CriticalSections threadsicher zu machen.
Hast du also eine Funktion welche die Daten bezieht, dann sieht das so aus
... char foo = 0; LockMyCriticalSection foo = threadunsafe_foo; ReleaseMyCiticalSection foo = doSomething(foo); LockMyCriticalSection threadunsafe_foo = foo; ReleaseMyCriticalSection ...Idealerweise ist "threadunsafe_foo" durch eine Zugriffsfunktion geschützt die eben dieses Lock und Release betreibt.
Verstehst du was ich meine?
-junix
-
Ach so, da ich das damals auf die Schnelle machen musste und mit TCriticalSection nicht auf Anhieb klar gekommen bin, hab ich das Problem mit TThreadList und darin abgelegten Objekten umgangen.
-
Ah, Danke!
das mit den Zugriffsfunktionen klingt logisch.Synchronize hat leider den Nachteil, das man damit Meiner Meinung nach keine Funktionen mit Parametern aufrufen kann. Oder geht das doch?
-
Nein, das geht nicht. Da hast du absolut recht. Wie gesagt: In aller Regel macht das Synchronisieren von ganzen Funktionen keinen Sinn. Denn im endeffekt müssen lediglich Schreib/Lese-Funktionen geschützt werden.
-junix
-
Ich habe noch einige Fragen bez. Threads.
Welche Daten müssen Threadsicher gemacht werden?
Ich erzeuge den Thread selber ja mit einem "new"cMailThread * Thread = new cMailThread(true);Der Thread wurde im Speicher also komplett neu angelegt. Meinem Verständis nach, müsste ich jetzt Properties des Threads selber nicht vor dem Zugriff anderer Threads schützen, da jeder Thread ja seine eigenen Daten im jeweils eigenen Speicher hat.
Bedeutet dass, das lediglich Zugriffe auf Daten (Variablen, Files, etc.) ausserhalb des Threads geschützt werden müssen, oder liege ich mit meinen obigen Auführungen daneben?Danke!
-
Clip schrieb:
Bedeutet dass, das lediglich Zugriffe auf Daten (Variablen, Files, etc.) ausserhalb des Threads geschützt werden müssen, oder liege ich mit meinen obigen Auführungen daneben?
Richtig. Du kannst dir diese Problematik ganz einfach vorstellen:
Stell dir vor, dein Speicherbereich ist eine Schublade die nach Links oder nach Rechts aus dem Schrank gezogen werden kann. Wenn jetzt nur immer einer links raus zieht (nur 1 Thread der auf den Speicherbereich zugreift), besteht kein Problem. Es kommt erst dann zukm Problem wenn einer Links einer Rechts steht (2 Threads die auf den selben Speicherbereich zugreifen) und die Möglichkeit besteht, dass beide gleichzeitig die Schublade öffnen wollen.
-junix