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 hatvoid __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.