TCriticalSection im Thread-Header deklariert.
-
Hallo,
ich habe eine Multi-Thread-Applikation. Jetzt stoppe (suspend()) ich den Thread in einem gewissen Zustand. Ich habe eine TCriticalSection im Thread-Header deklariert. Wenn ich mittels Acquire() auf die TCS zugreiffe und der Thread suspended ist, bleibt meine Anwendung hängen.
Werden public-Variablen auch suspendiert?
Danke!
-
Besteht nicht viel eher die Möglichkeit, das der Thread genau dann suspendiert wurde, wenn du in der CS steckst? Dann ist es naheliegend, das eine weitere Aquisition der CS einen Deadlock verursacht...
Folgende UMgehungsmöglichkeit würde ich vorschlagen:
Überschreib in deiner Threadableitung die Funktion "Suspend" und setzte in ihr lediglich ein SuspendRequest-Flag. Anschliessend prüfst du an einer sicheren Stelle in deinem Thread-Loop (z.B. vor jeder Aquise oder nach jedem Release der CS), ob das Flag gesetzt ist, und rufst - sollte es so sein - die Funktion TThread::Suspended() (genau so schreiben) auf. Damit hast du gewährleistet, das du sicher aus der CriticalSection raus bist, wenn der Thread zwangsruhe verordnet bekommt.
Eventuell würde es sich, angesichts dieser neuen Gesichtspunkte, auch lohnen, die CS über eine funktion zu aquirieren und freizugeben, die eben diese Prüfung vor nimmt. Damit könntest du dann auch die CS aus dem Public-Bereich (grr) deiner Klasse entfernen und brav in den Private-Bereich verschieben, wo sie auch hingehört.
-
junix schrieb:
Besteht nicht viel eher die Möglichkeit, das der Thread genau dann suspendiert wurde, wenn du in der CS steckst? Dann ist es naheliegend, das eine weitere Aquisition der CS einen Deadlock verursacht...
Folgende UMgehungsmöglichkeit würde ich vorschlagen:
Überschreib in deiner Threadableitung die Funktion "Suspend" und setzte in ihr lediglich ein SuspendRequest-Flag. Anschliessend prüfst du an einer sicheren Stelle in deinem Thread-Loop (z.B. vor jeder Aquise oder nach jedem Release der CS), ob das Flag gesetzt ist, und rufst - sollte es so sein - die Funktion TThread::Suspended() (genau so schreiben) auf. Damit hast du gewährleistet, das du sicher aus der CriticalSection raus bist, wenn der Thread zwangsruhe verordnet bekommt.
Eventuell würde es sich, angesichts dieser neuen Gesichtspunkte, auch lohnen, die CS über eine funktion zu aquirieren und freizugeben, die eben diese Prüfung vor nimmt. Damit könntest du dann auch die CS aus dem Public-Bereich (grr) deiner Klasse entfernen und brav in den Private-Bereich verschieben, wo sie auch hingehört.
hoi junix ;),
ich hab' das problem bereits anders gelöst nähmlich setzt ich in meiner Applikation ein Flag wenn ich den Thread nicht brauche, rufe das Flag im Thread bei jedem durchlauf auf und zweige in einen Stand-By-Mode ab, etwa so:
void __fastcall TMeinThread::Execute() { while (!Terminated) { switch(Flag) { case DEF_IDLE: Priority = tpIdle; // Priorität auf idle setzten Synchronize(Main_Frm->WriteTrace); // diese kleine Sache ist eben doch nötig, desshalb auch kein suspend Sleep(1); // Wenn ich den nicht drin habe, zeigt Windows im Taskmanager 99% CPU Nutzung an Application->ProcessMessages(); break; case DEF_RUN: // Ganzer Threadcode welcher schlafen geschikt wurde // Ganzer Threadcode welcher schlafen geschikt wurde // Ganzer Threadcode welcher schlafen geschikt wurde break; }
-
Ist doch eigentlich ganz ähnlich zu meinem Vorschlag.
Äh ... wozu Application ProcessMessages? Und du bist dir bewusst, das du so theoretisch unendlich schnell hintereinander "Main_Frm->WriteTrace" aufrufst? Das kann ja nicht der Sinn sein?
-
junix schrieb:
Ist doch eigentlich ganz ähnlich zu meinem Vorschlag.
Äh ... wozu Application ProcessMessages? Und du bist dir bewusst, das du so theoretisch unendlich schnell hintereinander "Main_Frm->WriteTrace" aufrufst? Das kann ja nicht der Sinn sein?
hm, ist mir schon klar, soll ich den delay eher 100ms gross machen?
verpassen kann ich erh nicht, die Daten zum tracen liegen in einer STL::Queue und ich der Funktion "Main_Frm->WriteTrace" lese ich ledigli h die Queue aus...
-
junix schrieb:
Man ist so alt wie man sich fühlt... - Augenblick! Wo zum Henker bleibt meine Rente?!?
Ach ja, hehe

-
roN schrieb:
junix schrieb:
Ist doch eigentlich ganz ähnlich zu meinem Vorschlag.
Äh ... wozu Application ProcessMessages? Und du bist dir bewusst, das du so theoretisch unendlich schnell hintereinander "Main_Frm->WriteTrace" aufrufst? Das kann ja nicht der Sinn sein?
hm, ist mir schon klar, soll ich den delay eher 100ms gross machen?
verpassen kann ich erh nicht, die Daten zum tracen liegen in einer STL::Queue und ich der Funktion "Main_Frm->WriteTrace" lese ich ledigli h die Queue aus...Wieso nicht irgendwie dann wenns sinn macht? Nämlich beim Zeichnen des formulars oder bei der Ankunft neuer Daten?
Keine Ahnung was für ne Updaterate du haben willst. Aber 1ms wären ja rund 1000 Bilder / Sekunde ... da ein Bildschrim es aber grade mal auf 60-100 Bilder/Sekunde schafft - mal ganz abgesehen von der Zeichnungsengine - dünkt mich das reichlich übertrieben.
-
junix schrieb:
Wieso nicht irgendwie dann wenns sinn macht? Nämlich beim Zeichnen des formulars oder bei der Ankunft neuer Daten?
Keine Ahnung was für ne Updaterate du haben willst. Aber 1ms wären ja rund 1000 Bilder / Sekunde ... da ein Bildschrim es aber grade mal auf 60-100 Bilder/Sekunde schafft - mal ganz abgesehen von der Zeichnungsengine - dünkt mich das reichlich übertrieben.Ich prüfe in der Funktion, ob noch Daten in der Queue vorhanden sind. Wenn keine mehr drin sind, komm' ich gleich wieder zurück...
-
Naja wie gesagt... die Häufigkeit ist der Eine Punkt. Der verschwendete Jump ein anderer. Vielleicht wäre es eleganter, auf ein Event zu warten, das beim eintreffen von Daten in die Queue gesetzt und auf das mittels Warte-Funktion im Thread gewartet (in dem die Zeit ans OS übergeben wird) wird? Das bringt die absolut minimalste CPU auslastung...
-
junix schrieb:
Naja wie gesagt... die Häufigkeit ist der Eine Punkt. Der verschwendete Jump ein anderer. Vielleicht wäre es eleganter, auf ein Event zu warten, das beim eintreffen von Daten in die Queue gesetzt und auf das mittels Warte-Funktion im Thread gewartet (in dem die Zeit ans OS übergeben wird) wird? Das bringt die absolut minimalste CPU auslastung...
Das ist korrekt, ich werde mal sehen, was sich tun lässt. Danke für den Tipp auf jedenfall.
