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
    - UnterThread

    Form 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 Unit1

    Form1->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-Thread

    Scan-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.


Anmelden zum Antworten