Objeckte von Threads
-
Hallo,
ich habe einen Thread, der seine Objekte um sich mit einer Datenbank zu verbinden selber mitbringt.
class TCopyAction : public TThread { private: protected: void __fastcall Execute(); void __fastcall DeleteComponents(); TSQLComponents * SQLAction; cSWLDB * DB; TCriticalSection* ThreadBlocker; };eine SQLConnection und weitere SQL Komponenten sind in dem DataModule "TSQLComponents" enthalten.
im Kontruktor des Threads werden die Objekte instantiert:
__fastcall TCopyAction::TCopyAction(bool CreateSuspended) : TThread(CreateSuspended) { // SQL Zugangsklassen werden insitialisiert. SQLAction = new TSQLComponents(NULL); DB = new cSWLDB; }Meinem Verständis nach müsste so jeder neu gestartete Thread seine eigenen SQL Komponenten haben.
Sinn des ganzen ist, eine Bandbreitenbegrenzung pro Connection seitens der DB auszutricksen. D.h. es werden 1 - 10 Threads gestartet, die jeweils andere Datenbankinhalte kopieren.
Leider kommt es andauernt zu Zugriffsverletzungen. Ich greife mit den Threads nur auf die Threadeigenen Komponenten zu, Zugriffe auf ein Formular oder ähnliches gibt es nicht.
Nur wenn ich fast den geasmten Code des Threads durch "Synchronize()" kontrolliere läuft alles glatt. Dummerweise läuft der Thread dann aber so liniar ab, dass alle Threads nacheinander abgearbeitet werden. D.h. ich könnte mit das Threading auch gleich schenken (benötigte Zeit ist auf diese Weise sogar noch etwas länger...).
Ich habe es auch schon mit "TCriticalSection" probiert, allerdings traten ebenfalls Zugriffsfehler auf.
Daher meine Fragen:
1. Wieso ist ein Objekt eines Threads nicht davor geschützt durch einen anderen Thread benutz zu werden, oder verstehe ich etwas elementares nicht?
2. Wenn es nicht so gehen sollte wie ich es mir gedacht habe, was wäre eine alternative Lösung meines Problems (aussser eine Liniare Abarbeitung, die überigens mit einem Thread auch funktioniert).Danke!
-
Du scheinst für jeden Thread eine eigene Criticalsection anzulegen. Benutz für alle Threads eine gemeinsame CriticalSection. Das könnte das Problem beheben.
Ansonsten: Deine SQL Komponenten scheinen nicht threadsicher zu sein.

-
Du scheinst für jeden Thread eine eigene Criticalsection anzulegen. Benutz für alle Threads eine gemeinsame CriticalSection. Das könnte das Problem beheben.
Also die CriticalSection in die Funktion welche den Thread aufruft, oder wie?
TCriticalSection* ThreadBlocker=new TCriticalSection(); ThreadBlocker->Acquire(); // Jedes Element des Stacks wird einem Thread als auszuführender Job übergeben, // Nach der Übergabe wird das Element aus dem Stack gelöscht. Der Druchlauf // erfolgt solange, bis der Stack leer ist. while (DokuXStack.size() != 0 && BreakRequested == false) { if (*Threads < MaxConnections) { // hier wird ein Thread gestarted. CopyAction = new TCopyAction(true); // Thread bekommt zu bearbeitenden Schlüssel CopyAction->X = DokuXStack.top(); DokuXStack.pop(); // Thread started CopyAction->Resume(); // Zähler wird erhöht. *Threads += 1; } ThreadBlocker->Release(); delete ThreadBlocker;