TThread , WaitForMultipleObjects , EAccessViolation
-
Hi
Ich habe in der Execute-Methode eines Threads die WaitForMultipleObjects Methode, beim ersten Aufruf klappt alles super, wird ein Event aufgerufen, wird der entsprechende Code ausgeführt , beim 2ten Aufruf von WaitForMultipleObjects wird immer eine EAccessViolation geworfen, ich hab ka warum. Es ist auch egal was für Code ich nach WairForMultipleObjects ausführe, der 2te Aufruf schlägt immer fehl.
Hier die Execute-Methode:
bool succesfull=false; m_bThreadShouldRun=true; try { while(!this->Terminated) { //hauptschleife, die immerwieder durchlaufen wird m_aktStatus="Hauptschleife"; //m_LastActionThread=GetTickCount(); //damit der rechner nicht an der leistungsgrenze läuft //Sleep(1); // //wenn initialisiert werden soll //neuer Code mit WaitForMultipleObjects DWORD event=WaitForMultipleObjects(6,m_AllEvents,false,INFINITE); switch(event) { case WAIT_OBJECT_0: //Starte ROD4 if(m_CanInit) { //zeugs für rauschunterdrückung initialisieren m_Bilder=new TMessung[m_AnzBilderRauschunterdrueckung]; for (int counter=0; counter<m_AnzBilderRauschunterdrueckung; counter++) { m_Bilder[counter].sPunkte=NULL; } //rod4 initialisierem if(InitRod4()) { m_CanInit=false; m_aktThreadStatus=STATUS_NONE; TRACE("Rod4 wurde initialisiert",false); } else { m_aktThreadStatus=STATUS_NONE; } } ResetEvent(m_EventStarteRod4); break; case WAIT_OBJECT_0+1: //Stoppe ROD4 //falls der rod4 initialisiert ist, dll freigeben if(m_CanInit==false) ReleaseRod4(); //es kann aktuell keine bild geliefert werden if(m_Bilder!=NULL) delete[] m_Bilder; if(PunkteBuffer!=NULL) delete[] PunkteBuffer; if(PunkteBufferBig!=NULL) delete[] PunkteBufferBig; if(m_bPointsFromFile) { for(int counter=0; counter<m_PunkteVektor.size(); counter++) { delete[] m_PunkteVektor[counter].sPunkte; } } m_Bilder=NULL; PunkteBuffer=NULL; PunkteBufferBig=NULL; //bildspeicher löschen m_CanGetBild=false; m_aktStatus="Beende dll"; //letzten error auf 0 setzen m_lastError=-1; m_AnzMesspunkte=0; m_PunkteAvailable=false; m_CanInit=true; m_aktBildStatus=STATUS_NOTHING; m_aktThreadStatus=STATUS_NONE; m_CanInit=true; m_bRod4ShouldRun=false; TRACE("DLL wurde freigegeben",false); ResetEvent(m_EventStoppeRod4); break; case WAIT_OBJECT_0+2: //MakeNewPicture //ein rauschfreies bild, aus den gesammelten erstellen m_aktStatus="Neues bild wird erstellt."; CreateRauschfreiesBild(); m_aktBildStatus=STATUS_NOTHING; ResetEvent(m_EventMakeNewPicture); break; case WAIT_OBJECT_0+3: //MakeReferenzScan TRACE("__DEBUG: ROD4Handler: NullScan wurde angefordert",true); MakeNullScan(m_aktNullScanName); bMakeNullScan=false; TRACE("__DEBUG: NullScan erstellt.",true); ResetEvent(m_EventMakeReferenzScan); break; case WAIT_OBJECT_0+4: //FindAllEdges m_aktBildStatus=STATUS_FINDEDGES; ClearEdgeArray(); succesfull=false; succesfull=FindAllEdges(0); //nachbearbeiten der gefundenen ecken if(succesfull) { //m_bCanGetEdges=NachbearbeitungEcken(); m_bCanGetEdges=true; } else { m_bCanGetEdges=false; } bFindEdges=false; m_aktBildStatus=STATUS_NOTHING; ResetEvent(m_EventFindAllEdges); break; case WAIT_OBJECT_0+5: //LoadNewPoints if(m_aktPunkte>=m_PunkteVektor.size()) { m_aktPunkte=0; //TRACE("Punkte zuende",true); m_aktThreadStatus=STATUS_STOPDLL; } else { //TRACE("Neue Punkte laden:"+IntToStr(m_aktPunkte),true); NextPointsFromFile(m_PunkteVektor.at(m_aktPunkte)); m_aktPunkte++; //m_LastTimeNewPoints=GetTickCount(); } //ResetEvent(m_EventLoadNewPoints); break; default: //fehler break; }Hab auch schon gegoogelt, die Forensuche benutzt, aber nicht wirklich eine Lösung gefunden, wäre für jeden Vorschlag dankbar.
Mfg
Reinhold Fischer
/Edit : Bitte beim nächsten Posten von Code beachten das es auch extra Tags für C++ Code gibt!
-
Was ich noch vergessen habe:
m_AllEvents wird folgendermaßen erstellt:
m_AllEvents=new HANDLE[6]; m_AllEvents[0]=m_EventStarteRod4; m_AllEvents[1]=m_EventStoppeRod4; m_AllEvents[2]=m_EventMakeNewPicture; m_AllEvents[3]=m_EventMakeReferenzScan; m_AllEvents[4]=m_EventFindAllEdges; m_AllEvents[5]=m_EventLoadNewPoints;Und so werden die Events erstellt:
m_EventStarteRod4=CreateEvent(NULL,true,false,"StarteRod4"); m_EventStoppeRod4=CreateEvent(NULL,true,false,"StoppeRod4"); m_EventMakeNewPicture=CreateEvent(NULL,true,false,"MakeNewPicture"); m_EventMakeReferenzScan=CreateEvent(NULL,true,false,"MakeReferenzScan"); m_EventFindAllEdges=CreateEvent(NULL,true,false,"FindAllEdges"); m_EventLoadNewPoints=CreateEvent(NULL,true,false,"LoadNewPoints");Mfg
Reinhold Fischer
-
Wirf mal den Debugger an und schau nach, in welcher Zeile der Fehler passiert.
-
der debugger wirft mich genau bei WaitForMultipleObjects raus.
-
ReinholdFischer schrieb:
m_AllEvents wird folgendermaßen erstellt:
[...]
Und so werden die Events erstellt:
[...]
Mfg
Reinhold Fischer
In welcher Reihenfolge passiert denn das? (ich hoffe doch, daß du erst deine Exents anlegst und dann in das Array reinwirfst).
-
Dann bleibt ja nur die Möglichkeit, dass eines der Events gelöscht wurde.
-
Ja klar, zuerst Events erstellen, dann in den Array gepackt.
@Joe_M.:
die Überlegung hatte ich auch schon, werde das ma genauer überprüfen, aber direkt im Quellcode steht davon nichts explizit.
Das ResetEvent hat damit nichts zu tun, oder?
Mfg
Reinhold Fischer
-
Also, es wird immer komischer, jetzt bekomme ich die AccessViolation schon beim ersten Aufruf von WaitForMultipleObjects, AllEvents ist zur Laufzeit mit Daten gefüllt, kein Nullzeiger dabei.
Mfg
Reinhold Fischer
-
Also, den ersten Fehler habe ich gefunden, ich erstelle den TThread mit false im Konstruktor, also das er sofort losläuft.
Dadurch ist es zeitweise vorgekommen, das die Execute-Methode angelaufen ist, bevor m_AllEvents erstellt wurde.
Mfg
Reinhold Fischer
-
Ich habe aus dem Pointer m_AllEvents ein festes Array gemacht, seitdem gibts keine EInvalidAccess Exception mehr, jedoch liefert WaitForMultipleObjects jetzt WAIT_FAILED zurück, GetLastError liefert Handle is invalid.
Ich hab jedoch ka warum.
Irgendwelche Ideen?
Mfg
Reinhold Fischer