TThread-Problem



  • Hallo zusammen,
    icxh hab' in meiner Anwendung, die Daten welche ich bis anhin in einem Timer zyklisch abgefragt habe, in einen eigenen Thread gepackt. Jetzt siehht es so aus, als ob der Thread zwischendurch immer wieder unterbrochen wird, was beim Timer nicht der Fall war. mit dem Timer funktionierte es einwandfrei. Kann ich irgendwie die gesamte Execute-Funktion im Thread, Threadsicher machen d.h., das kein anderer Thread dazwischen kommen kann?
    Bei dem Code im Thread handelt es sich um eine Kommunikation über den Profibus, welche nicht unterbrochen werden darf...
    der Code:

    void __fastcall TTimerThread::Execute()
    {
    while (!Terminated)
            {
    /* EasyCODE < */
        Main_Frm->Timer1->Tag=1; // tag variable setzen damit ich bestimmen kann, dass der Timer läuft
    
    /* EasyCODE > */
        /* EasyCODE - */
    /* EasyCODE < */
        int result_int; // Speicher für resultat Empfang der  Ist-Werte
    
        //Nur wenn Init-Button schon disabled ist.
    
    /* EasyCODE > */
        if( Main_Frm->Init_Btn->Enabled==false )
        {
            Main_Frm->Profi_p->RecParam(&Main_Frm->sendData, 40);
    
            result_int=Main_Frm->result.PWE1 | (Main_Frm->result.PWE2<<16);
            Main_Frm->TrackBar1->Position = (int)result_int;
            if( Main_Frm->lan )
            {
                // Je nach aktuell eingestellter Sprache, Ausgabe generieren
                Main_Frm->Istpos_Lab->Caption = "Istposition: "+ AnsiString((int)result_int) + Main_Frm->Einheit_CB->Text;
                Main_Frm->Label5->Caption = "Momentane Position: "+ AnsiString((int)result_int) + Main_Frm->Einheit_CB->Text;
            }
            else 
            {
                Main_Frm->Istpos_Lab->Caption = "Actual position: "+ AnsiString((int)result_int) + Main_Frm->Einheit_CB->Text;
                Main_Frm->Label5->Caption = "Actual Position: "+ AnsiString((int)result_int) + Main_Frm->Einheit_CB->Text;
            }
    /* EasyCODE < */
            /*** NUR wenn PPO2 eingestellt ist!***/
    
    /* EasyCODE > */
            if( Main_Frm->RadioGroup1->ItemIndex == 1 )
            {
                Main_Frm->Profi_p->RecParam(&Main_Frm->sendData, 29);
                result_int=Tools::HexStringToShort(AnsiString(IntToHex(Main_Frm->result.PWE2,2)+IntToHex(Main_Frm->result.PWE1,0)));
                if( Main_Frm->lan             // Je nach aktuell eingestellter Sprache, Ausgabe generieren
                  )
                {
                    Main_Frm->Label44->Caption = "Iststrom: "+ AnsiString((short)result_int) + "mA";
                }
                else
                {
                    // short-Wandlung weil der Stromwert eine signed 16bit Var ist
                    Main_Frm->Label44->Caption = "Actual current: "+ AnsiString((short)result_int) + "mA";
                }
                for( int i=0; i<=5000 && IntToHex(Main_Frm->result.PKE,2) != "102A" && IntToHex(Main_Frm->result.PKE,2) != "202A"; i++ )
                {
                    Main_Frm->Profi_p->RecParam(&Main_Frm->sendData, 42);
                    Main_Frm->Profi_p->ReadSlave(Main_Frm->SlaveID_ED->Text.ToInt(),&Main_Frm->result);
                    //Application->ProcessMessages();
                }
                result_int=Tools::HexStringToShort(AnsiString(IntToHex(Main_Frm->result.PWE2,2)+IntToHex(Main_Frm->result.PWE1,0)));
                if( Main_Frm->lan             // Je nach aktuell eingestellter Sprache, Ausgabe generieren
                  )
                {
                    Main_Frm->Istgesch_Lab->Caption = "Istgeschwindigkeit: "+ AnsiString((short)(((float)(short)result_int/16384)*100)) + "%";
                }
                else
                {
                    Main_Frm->Istgesch_Lab->Caption = "Actual speed: "+ AnsiString((((short)result_int/16384)*100)) + "%";
                }
            }
    /* EasyCODE < */
            /***********************/
             //Fehler von Motor auslesen und anzeigen
             // erst auslesen wieviele Fehler anstehen damit der letzte angezeigt werden kann
    
    /* EasyCODE > */
            if( Main_Frm->result.PZD1&0x0008 // Wenn Störung anliegt, dann...
              )
            {
                Main_Frm->Profi_p->RecParam(&Main_Frm->sendData, 952);
                          Main_Frm->Profi_p->ReadSlave(Main_Frm->SlaveID_ED->Text.ToInt(),&Main_Frm->result);
                          result_int=Tools::HexStringToShort(AnsiString(IntToHex(Main_Frm->result.PWE2,2)+IntToHex(Main_Frm->result.PWE1,0)));
                          Main_Frm->sendData.IND=result_int; // IND auf den letzten Fehler zeigen lassen und den letzten Fehler anzeigen
                /************* FEHLER *********************************************************/
                          Main_Frm->Profi_p->RecParam(&Main_Frm->sendData, 947);
    
                            result_int=Tools::HexStringToShort(AnsiString(IntToHex(Main_Frm->result.PWE2,2)+IntToHex(Main_Frm->result.PWE1,0)));
                            Main_Frm->FehlerTitel_Lab->Font->Color= clRed;
                            Main_Frm->FehlerTitel_Lab->Caption= "Fehler!";
                            Main_Frm->ErrNum_Lab->Caption=AnsiString(result_int);
                switch( result_int )
                {
                case 1 :
                    Main_Frm->ErrDisc_Lab->Caption="Temperatur Elektronik";
                    break;
                case 2 :
                    Main_Frm->ErrDisc_Lab->Caption="Temperatur Drehstrombrücke";
                    break;
                case 4 :
                    Main_Frm->ErrDisc_Lab->Caption="Unterspannung";
                    break;
                case 8 :
                    Main_Frm->ErrDisc_Lab->Caption="_berspannung";
                    break;
                case 16 :
                    Main_Frm->ErrDisc_Lab->Caption="Buskommunikation";
                    break;
                case 32 :
                    Main_Frm->ErrDisc_Lab->Caption="Kommunikationsfehler";
                    break;
                case 64 :
                    Main_Frm->ErrDisc_Lab->Caption="Timeout";
                    break;
                case 128 :
                    Main_Frm->ErrDisc_Lab->Caption="Rechenfehler";
                    break;
                case 256 :
                    Main_Frm->ErrDisc_Lab->Caption="Sensor Fehler";
                    break;
                case 512 :
                    Main_Frm->ErrDisc_Lab->Caption="Batterie Low";
                    break;
                }
                result_int=result_int>>1;
            }
            else 
            {
                Main_Frm->FehlerTitel_Lab->Font->Color= clLime;
                Main_Frm->FehlerTitel_Lab->Caption= "kein Fehler!";
                Main_Frm->ErrNum_Lab->Caption="-";
                Main_Frm->ErrDisc_Lab->Caption="-";
            }
            /******************************************************************************/
            /************* WARNUNG ********************************************************/
                            AnsiString out_AS,bit_AS;
    
                            Main_Frm->Profi_p->RecParam(&Main_Frm->sendData, 953);
                            unsigned short result_ush=Tools::HexStringToShort(AnsiString(IntToHex(Main_Frm->result.PWE2,2)+IntToHex(Main_Frm->result.PWE1,0)));
                            Main_Frm->Label46->Caption=AnsiString(result_ush);
            for( int shift_int=16;shift_int>=0;shift_int-- )
            {
                if( (result_ush>>shift_int)&0x01 )
                {
                    out_AS+="1";
                    if( bit_AS!="" )
                    {
                        bit_AS+=", "+ AnsiString(shift_int+1);
                    }
                    else
                    {
                        bit_AS+="Bit"+ AnsiString(shift_int+1);
                    }
                }
                else 
                {
                    out_AS+="0";
                }
            }
            Main_Frm->Label46->Caption=out_AS;
            Main_Frm->Label60->Caption=bit_AS;
    
            /******************************************************************************/
                    Main_Frm->show_STW->Caption= "Steuerwort (STW) in HEX: "+IntToHex(Main_Frm->sendData.PZD1,4);
            if( Main_Frm->result.PKE != 0 )
            {
    /* EasyCODE < */
                Main_Frm->Label37->Caption= "Zustandswort (ZSW) in HEX: "+IntToHex(Main_Frm->result.PZD1,4);
    
       /*               if(result.PZD1 &ZSW_EINSCHALTBEREIT == ZSW_EINSCHALTBEREIT)
                        {
                        Label52->Font->Color=clLime;
                        Label52->Caption= "Bedutung: EINSCHALTBEREIT";
                        }
       */             if(Main_Frm->result.PZD1 &ZSW_EINSCHALTSPERRE)
                        {
                        Main_Frm->Label52->Font->Color=clRed;
                        Main_Frm->Label52->Caption= "Bedutung: EINSCHALTSPERRE";
                        }
                      else if(Main_Frm->result.PZD1 &ZSW_ANTRIEB_FAEHRT)
                        {
                        Main_Frm->Label52->Font->Color=clBlue;
                        Main_Frm->Label52->Caption= "Bedutung: FAHRAUFTRAG AKTIV";
                        }
                      else if(Main_Frm->result.PZD1 &ZSW_STOERUNG)
                        {
                        Main_Frm->Label52->Font->Color=clRed;
                        Main_Frm->Label52->Caption= "Bedutung: STOERUNG";
                        }
                      else if(Main_Frm->result.PZD1 &ZSW_EINSCHALTBEREIT == ZSW_EINSCHALTBEREIT)
                        {
                        Main_Frm->Label52->Font->Color=clLime;
                        Main_Frm->Label52->Caption= "Bedutung: EINSCHALTBEREIT";
                        }
                      else
                        {
                        Main_Frm->Label52->Font->Color=clWindowText;
                        Main_Frm->Label52->Caption= "Bedutung:";
                        }
    
    /* EasyCODE > */
            }
        }
    /* EasyCODE < */
        Main_Frm->Timer1->Tag=0; // tag variable reseten damit ich bestimmen kann, dass der Timer nicht läuft
    }
    /* EasyCODE > */
    
    }
    /* EasyCODE ) */
    /* EasyCODE ( 69*/
    //---------------------------------------------------------------------------
    


  • Lies dir einmal die Beschreibung zu TThread::Synchronize durch, dann wirst du schon einmal den ersten Fehler in deinem Thread finden.

    Rainer



  • Hallo roN,
    versuch es doch bitte mal auf die Weise wie auch RaKo schon vorgeschlagen hat

    void __fastcall TSendPosFunk::Execute()
    {
    	int			ret = 0;			// Fehlercode der Funktionen
    
    	while (!Terminated)		// Endlos-Schleife des Thread
    	{
    		// Warten auf die Ereignisse
    		ret	=	WaitForMultipleObjects(2, FluPosEvent, False, INFINITE);
    
    		// Ein Thread-Ereignis ist aufgetreten?
    		switch (ret - WAIT_OBJECT_0)
    		{
    			case FluPos_Event:
    			{
    				Synchronize(BearbeiteEreignis);	// Ereignis bearbeiten
    			break; }
    			// Thread beenden
    			case FluPos_End:	{
    				Terminate();							// beenden des Thread
    			break; }
    			default:	{
    				// Fehler in den Logfile schreiben
    				ErrText->msgErrorInt
    							(2,
    							IFEHLER,
    							"[TSendPosFunk::Execute]",
    							" Ein unbekanntes Ereignis ist aufgetreten!");
    			break; }
    		}			// Ende: switch (ret - WAIT_OBJECT_0)
    	}				// Ende: while (!Terminated)
    }					// Ende: Funktion
    

    In BearbeiteEreignis ist dann der auszuführende Code enthalten

    Evi48



  • Noch eine Enttäuschung: warum lässt du es ihn nicht erstmal versuchen?



  • Weil ich weiss wie sehr man sich über ein paar Zeilen Code freuen kann. Warum soll man jemand zappeln lassen wenn man glaubt eine Lösung in der Schublade zu haben?

    Evi48



  • Weil selbst erarbeitete Lösungen wertvoller sind als vorgesagte.
    Ausserdem ist es fraglich, dass roN nach dem Hinweis von rako überhaupt noch "gezappelt" hat.


Anmelden zum Antworten