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.



  • @CStoll:

    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


Anmelden zum Antworten