Programm friert ein

Alles rund um die Programmierung mit Qt
Antworten
daffi
Beiträge: 23
Registriert: 2. Januar 2011 18:44

Programm friert ein

Beitrag 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
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag 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..
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Kann es sein, dass du zu viele repaints triggerst?
daffi
Beiträge: 23
Registriert: 2. Januar 2011 18:44

Beitrag 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?
kater
Beiträge: 306
Registriert: 29. Dezember 2009 01:13
Wohnort: Darmstadt

Beitrag 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.
softwaremaker
Beiträge: 149
Registriert: 1. April 2009 19:25

threads

Beitrag 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();
daffi
Beiträge: 23
Registriert: 2. Januar 2011 18:44

Beitrag von daffi »

Danke an euch, ich werde es morgen einmal ausprobieren!
daffi
Beiträge: 23
Registriert: 2. Januar 2011 18:44

Beitrag von daffi »

So habe es mithilfe eines QTimers hinbekommen.
Funktionioert nun,Danke!
Antworten