Seite 1 von 1

Programm friert ein

Verfasst: 6. Januar 2011 18:08
von daffi
Hi Leute,

mein Programm geht ohne Umschweife zu starten, läuft auch ohne Probleme. (Bei mir @home)

Wenn ich dies allerdings auf Arbeit laufen lasse, (langsame Rechner) bleibt die Graphische Ausgabe irgendwann hängen.

Die Operationen werden allerdings noch im Hintergrund ausgeführt.

Wie kann ich das ganze syncronisieren?

Danke
Daffi

Verfasst: 6. Januar 2011 18:39
von solarix
Ein Programm bleibt nicht einfach hängen. Ich tippe auf einen Softwarefehler, welcher sich je nach System(-Timing) unterschiedlich auswirkt.
Z.B. eine Multithreading-Applikation mit GUI-Operationen in den Threads, welche auf einem schnellen System häufig aneinander vorbeikommen (und der Fehler daher selten auftritt), jedoch auf einem langsamen nicht mehr und sich daher der Fehler häufiger bemerkbar macht.

Daher: ohne Code kann man nicht sagen, wo der Fehler liegt...

hth..

Verfasst: 6. Januar 2011 21:32
von franzf
Kann es sein, dass du zu viele repaints triggerst?

Verfasst: 6. Januar 2011 21:56
von daffi
Ok es geht drum mehrere Tausend Files einzulesen, zu decodieren und neu zu schreiben.

Es gibt 2 große Schleifen...

einmal alle Verzeichniss auf einen Vektor einzulesen:

Code: Alles auswählen

		for ( directory_iterator dir_itr( full_path ); dir_itr != end_iter; ++dir_itr ){
			try{
				//Bei einem Unterverzeichnis
				if ( is_directory( dir_itr->status() ) ){
					
					//suche die devList.dat & die devParm.dat
					string devParm = full_path.directory_string() + "\\" + dir_itr->path().filename() + "\\devParm.dat";
					string devList = full_path.directory_string() + "\\" + dir_itr->path().filename() + "\\devList.dat";

					//Wenn beide im Unterordner vorhanden sind ...
					if (is_regular_file( devList ) && is_regular_file( devParm )){
						//Fülle das Array mit dem Pfad an den die beiden Datein gefunden wurden
						dir.push_back(full_path.directory_string() + "\\" + dir_itr->path().filename());
						filecounter++;
					}
				}
				//Wenn ein normales File gefunden wird --> gucken ob devParm oder devList
				else if ( is_regular_file( dir_itr->status() ) ){

					string devParm = full_path.directory_string() + "\\devParm.dat";
					string devList = full_path.directory_string() + "\\devList.dat";

					//gucke ob devParm und devList vorhanden sind

					if((List!=1) && (is_regular_file( devList )))
						List=1;
					else if ((Parm!=1) && (is_regular_file( devParm )))
						Parm=1;

					//Wenn beide da sind
					if (List && Parm){
						//gib den Haupt-Pfad zurück
						dir.push_back(full_path.directory_string());
					}
				}

			}
			//Ausnahmenbehandlung
			catch ( const std::exception & ex ){
			cout << dir_itr->path().filename() << " " << ex.what() << endl;
			}
		}//Ende for
zum anderen in jedem Verzeichnis die Datein zu decodieren und wieder neu abzulegen.

Code: Alles auswählen

for (int i = 0;i<pfad.size();i++)
	{
		//Legt einen Vektor zum speichern von allen ID´s an
		//Vektor beinhaltet Klasse data_ID - speichert alle Eigenschaften aller ID´s
		vector <data_ID> IDs;

		//Einlesen der Data-IDs aus devList.dat und devParm.dat
		unsigned long counted_dataIDs=read_files( pfad[i] ,IDs);
		if (counted_dataIDs==1){
			//ins Errorfile eintragen
			cerr<<endl<<"Problem beim einlesen der Daten!"<<endl;
			cerr<<pfad[i]<<endl<<endl;

			//Messagebox bei Fehler ausgeben
			QMessageBox msgBox;
			msgBox.setIcon(QMessageBox::Critical);
			//Messagebox in die Länge ziehen
			msgBox.setText("Problem beim einlesen der Daten!                                                                                                    ");
			msgBox.setInformativeText("Programm wird beendet - Bitte bestätigen ...");
			msgBox.exec();

			error=1;
			beenden();
			break;
		}


		//Schreiben der Daten in das Ausgabe File
		if (write_to_file(pfad[i],IDs,counted_dataIDs,ui)==1){
			//ins Errorfile eintragen
			cerr<<endl<<"Problem beim schreiben der Daten!"<<endl;
			cerr<<pfad[i]<<endl<<endl;
			//Messagebox bei Fehler ausgeben
			QMessageBox msgBox;
			msgBox.setIcon(QMessageBox::Critical);
			//Messagebox in die Länge ziehen
			msgBox.setText("Problem beim schreiben der Daten!                                                                                                    ");
			msgBox.setInformativeText("Programm wird beendet - Bitte bestätigen ...");
			msgBox.exec();

			error=1;
			beenden();
			break;
		}

		//Progressbar setzen - Fortschritt berechnen
		progress+=(float)100/pfad.size();
		ui.progressBar->setValue (ui.progressBar->value()+progress);

		//Globale Variablen zurücksetzen
		positionszeiger_devList = 4;									//Positionszeiger auf DevList
		positionszeiger_devParm = 0;									//Positionszeiger auf DevParm
		tmpID = 0;														//Speichert temporär die aktuelle ID -> für Übergang zu User Files
		userID_flag=0;													//UserID´s Ja oder Nein

		ui.textEdit_ausgabe->append("------------------------------------------------------------------------------------\n"); 


		[color=red]QCoreApplication::processEvents(QEventLoop::AllEvents);[/color]
	}
Wenn ich die rote Anweisung Einfüge kommt das Einfrieren nicht mehr.
Die Ausgabe in die Texteditbox scheint nun syncon zu sein,jedoch die Progressbar füllt sich viel zu schnell ...

Ich habe die Werte des Fortschritts ausgeben lassen und diese sollten eigentlich richtig sein.

Meine Vermutung der Rechner kommt nicht mit den vielen aufwendigen Operationen mit.

@Franzf meinst du mit repaint,dass ich zu viele Ausgaben mache?

Verfasst: 6. Januar 2011 23:41
von kater
daffi hat geschrieben: einmal alle Verzeichniss auf einen Vektor einzulesen:
Ohne jetz genauer den Code anzuschauen... Aber ich denke, dass ich Teil des Fehlers. Bei großen Daten wird dir irgendwann der RAM zulaufen. Und dann kommt der SWAP und der ist lahm.

Also schau erstmal wieviel RAM die Kisten haben und wieviel so das Programm verbraucht.

threads

Verfasst: 6. Januar 2011 23:53
von softwaremaker
Packe den ganzen Berechnungsteil einfach in einen Thread, dann friert die GUI nicht ein.

Code: Alles auswählen

class MyThread : public QThread
{
    Q_OBJECT

public:
   MyThread ( QObject *parent = 0 );
    ~MyThread ();
    void run();
    QTimer  m_timer;
    int   m_progressvalue;
private slots:
    void timerEvent();
};

Code: Alles auswählen

MyThread ::MyThread ( QObject *parent ) :
        QThread(parent)
{
}

void MyThread ::run()
{
    m_progressvalue = 0;
   
     //timer sorgt für die Aktualisierung des Progress-Controls
    connect( &m_timer, SIGNAL(timeout()), this, SLOT(timerEvent()) );
    m_timer.start( 2000 ); //alle 2 sekunden

    // hier die Berechnung usw. rein
    // und progressvalue berechnen
}

void MyThread ::timerEvent()
{ 
   //hier Progress-Control mit m_progressvalue aktualisieren
}
und irgenwo dann starten

Code: Alles auswählen

MyThread meinthread;

meinthread.start();

Verfasst: 7. Januar 2011 00:13
von daffi
Danke an euch, ich werde es morgen einmal ausprobieren!

Verfasst: 9. Januar 2011 20:05
von daffi
So habe es mithilfe eines QTimers hinbekommen.
Funktionioert nun,Danke!