Umgang mit Threads
-
Hi
Ich frang grad am mit Threads und hab auch schon ein laufendes Programm, jedoch kommt es ab und zu zu Schreibkonflickten und fehlern...
Mein Programmaufbau:
Form1
- ScanThread
- UnterThreadForm 1 ist eine normale Anwendung.
Von da aus kann der User mittels Button den Scan-Thread starten.
Dieser soll solange laufen bis der User den Stop-Button betätigt.
Das klappt wunderbar.void __fastcall TForm1::Btn_StopClick(TObject *Sender) { if(NewScanThread) NewScanThread->Terminate(); }
In diesem Thread werden dann aber weitere Threads gestartet (wusste net wie ich das sonst machen sollte).
Hier die erste frage:
Diese sollen alle sofort beendet werden, wenn auch der ScanThread beendet wird!
Wie stelle ich das an?Dann:
Ich nutze von diesen Unterthreads aus eine Funktion in Unit1Form1->newLine(X1,Y1,X2,Y2); Form1->writeLog(Meldung);
Dabei kommt es ab und zu zu Ausnahmefehlern!
Währe es daher sinnvoller diese zwei funktionen in den Unterthread nochmal abzubilden und nicht auf Unit1 zuzugreifen?Vielen Dank für eure Hilfe
-
Den anderen Threads mitteilen, dass sie sich beenden sollen, kannst du z.B. über ein Event oder einfach über eine boolsche Variable, auf die alle Threads einen Zeiger haben.
EDIT: Eine weitere Möglichkeit ist, den Status deines ScanThreads abzufragen per GetExitCodeThread. "Ist er beendet, beende ich mich auch!"
-
hm, ok
ich habs jetzt so versucht:
unsigned long Stat; GetExitCodeThread(Form1->NewScanThread, &Stat); if(Stat == STILL_ACTIVE) {
Aber da geht er nie in die If-anweisung.
sonder in die else!Wäre WaitForSingleObject noch eine variante die ich irgendwie nutzen könnte?
Das halt der Scan-Thread mit dem Aufruf weitere Unterthreads wartet, bis der erste Unterthread beendet ist?es läuft quasi so ab:
Form1-> starte den Scan-ThreadScan-Thread->durchlauf eine Endlosschleife bis der User Stop drückt
Scan-Thread->Endlosschleife-> starte pro Durchlauf 10 Unterthreads (welche unterschiedlich lange zum abarbeiten brauchen)Ich hätte jetzt gern, das der Scan-Thread mit dem aufruf weiterere Threads solange warte, bis der jeweilig aktive Unterthread beendet ist.
(hoffe ich konnte mich verständlich ausdrücken)
-
Hier mal mein Versuch:
do { if ((time(0) - aktZeit)>(Pause * Zeit / 1000)) { for(int i=0; i < Pakete; i++) { Synchronize(&Scan); if(Terminated) { Form1->ThreadStop(); return; } } aktZeit = time(0); } if(Terminated) { Form1->ThreadStop(); return; } } while (1);
Scan:
void __fastcall ScanThread::Scan() { Form1->FCount++; //Starten des Ping-Threads NewPingThread= new PingThread(false); if(!NewPingThread) { Form1->writeLog("Ping-Thread konnte nicht erstellt werden.",true); return; } NewPingThread->Count = Form1->FCount; if(WaitForSingleObject(NewPingThread,INFINITE) == WAIT_OBJECT_0) NewPingThread->Terminate(); }
Die Enlosschleife ruft aller Sekunden die interne for-schleife auf.
In der For-Schleife soll der Thread aber solange warten, bis der eben gestartetet Unterthread NewPingThread beendet ist (dies kann bis zu 200ms dauern). erst dann soll ein neuer NewPingThread erzeugt werden.