Seite 1 von 1

Speicherfresser und hohe Prozessorlast

Verfasst: 31. Januar 2008 21:15
von methusalem
Moin,

auch ich hab nun mein kleines Tool für QExtSerialPort fast fertig.

Leider musste ich feststellen, das mein Programm eine hohe CPU Last verursacht und das es scheinbar auch Speicher frisst.

Ich glotze nun schon so lange auf den Quellcode, das ich die Fehler scheinbar nicht mehr finde. Hat jemand ne Idee?

Als Anlage das komplette Projekt und hier die zwei cpp Dateien. Es dürften wohl nur die beiden Methoden ReadThread::run() und StdBase::reciveData() interessant sein.

readthread.cpp

Code: Alles auswählen

#include "readthread.h"
#include <QFile>
#include <QTextStream>

ReadThread::ReadThread() {
	serPort = new QextSerialPort("COM6");
	serPort->setBaudRate(BAUD4800);   
	serPort->setFlowControl(FLOW_HARDWARE);
	serPort->setParity(PAR_NONE);
	serPort->setDataBits(DATA_8);
	serPort->setStopBits(STOP_1); 
}

ReadThread::~ReadThread() { 
	serPort->close();
}

void ReadThread::start(){
	//Metode eigentlich überflüßig!
	//zur kontrolle drinn gelassen.
	QThread::start();
}

void ReadThread::stop(){
	running=false;
	serPort->close();
}

void ReadThread::run(){

	running = true;

	int numBytes = 0;
	char buff[1024]="";
	QByteArray RS232Buffer;

	/*
	QFile file("output.txt");
    if (!file.open(QIODevice::WriteOnly | QIODevice::Append))
         return;
    QTextStream outstream(&file);
	*/

	printSettings();

	serPort->open(QIODevice::ReadOnly);

	while(running){

		numBytes = serPort->bytesAvailable();
		
		if(numBytes > 0){

			strcpy(buff,"");
			
			if(numBytes > 1024){
				numBytes = 1024;
			}
		
			int i = serPort->read(buff, numBytes);
			
			//outstream << buff;

            for(int k=0;k<numBytes;k++){
               RS232Buffer.append(buff[k]);
            }
            emit recivedBuffer(RS232Buffer,numBytes);
		}
	}
}

void ReadThread::setEnv(int env,int value){
	
	switch(env){
		case SPEED:
			serPort->setBaudRate(BaudRateType(value));
			printSettings();
			break;
		case DATABITS:
			serPort->setDataBits(DataBitsType(value));
			printSettings();
			break;
		case PARITY:
			serPort->setParity(ParityType(value));
			printSettings();
			break;
		case STOPPBITS:
			serPort->setStopBits(StopBitsType(value));
			printSettings();
			break;
		case FLOW:
			serPort->setFlowControl(FlowType(value));
			printSettings();
			break;
		default:
			qDebug("default");
			break;
	}
	printSettings();
}

void ReadThread::setEnv(QString portname){
	serPort->setPortName(portname);
	printSettings();
}

void ReadThread::printSettings(){

	qDebug("port: %s",serPort->portName().toAscii().data());
	qDebug("speed: %d",serPort->baudRate());
	qDebug("databits: %d",serPort->dataBits());
	qDebug("parity: %d",serPort->parity());
	qDebug("stoppbits: %d",serPort->stopBits());
	qDebug("flow: %d",serPort->flowControl());
	qDebug("===");

}
hauptfenster.cpp

Code: Alles auswählen

#include "hauptfenster.h"
#include <QMessageBox>

StdBase::StdBase(QWidget *parent){
	setupUi(this);
	
	p_readThread = new ReadThread();
	
	connect(p_readThread, SIGNAL(recivedBuffer(QByteArray, int)), 
		this, SLOT(reciveData(QByteArray, int)));
}

StdBase::~StdBase(){
	delete p_readThread;
}

void StdBase::reciveData(QByteArray RS232Buffer, int numBytes){
	QString output = QString(RS232Buffer);
	te_output->append(output);
}

void StdBase::on_pb_open_clicked(){
	p_readThread->setEnv(le_port->text());
	p_readThread->setEnv(SPEED,cb_speed->currentIndex());
	p_readThread->setEnv(DATABITS,cb_datenbits->currentIndex());
	p_readThread->setEnv(PARITY,cb_parity->currentIndex());
	p_readThread->setEnv(STOPPBITS,cb_stoppbits->currentIndex());
	p_readThread->setEnv(FLOW,cb_flowcontrol->currentIndex());
	
	p_readThread->start();
	
	pb_close->setEnabled(true);
	pb_open->setDisabled(true);
	pb_clear->setEnabled(true);

	le_port->setDisabled(true);
	cb_speed->setDisabled(true);
	cb_datenbits->setDisabled(true);
	cb_parity->setDisabled(true);
	cb_stoppbits->setDisabled(true);
	cb_flowcontrol->setDisabled(true);
}

void StdBase::on_pb_close_clicked(){
	p_readThread->stop();

	pb_open->setEnabled(true);
	pb_close->setDisabled(true);

	le_port->setDisabled(false);
	cb_speed->setDisabled(false);
	cb_datenbits->setDisabled(false);
	cb_parity->setDisabled(false);
	cb_stoppbits->setDisabled(false);
	cb_flowcontrol->setDisabled(false);
}

void StdBase::on_cb_speed_activated(int index){
	p_readThread->setEnv(SPEED,index);
}

void StdBase::on_cb_datenbits_activated(int index){
	p_readThread->setEnv(DATABITS,index);
}

void StdBase::on_cb_parity_activated(int index){
	p_readThread->setEnv(PARITY,index);
}

void StdBase::on_cb_stoppbits_activated(int index){
	p_readThread->setEnv(STOPPBITS,index);
}

void StdBase::on_cb_flowcontrol_activated(int index){
	p_readThread->setEnv(FLOW,index);
}

void StdBase::on_le_port_textChanged(QString portname){
	p_readThread->setEnv(le_port->text());
}

Verfasst: 31. Januar 2008 21:48
von upsala
Gönn deiner while-Schleife in der Funktion run zumindest mal ein msleep(1) oder so, so schnell wie dein Prozessor die Schleife abarbeitet ist keine Serielle-Schnittstelle.

Verfasst: 1. Februar 2008 15:27
von methusalem
So, noch ne Frage zu meinem Speicherfresser:

Code: Alles auswählen

   while(running){

      numBytes = serPort->bytesAvailable();
      
      if(numBytes > 0){

         strcpy(buff,"");
         
         if(numBytes > 1024){
            numBytes = 1024;
         }
      
         int i = serPort->read(buff, numBytes);
         
         //outstream << buff;

            for(int k=0;k<numBytes;k++){
               RS232Buffer.append(buff[k]);
            }
            emit recivedBuffer(RS232Buffer,numBytes);
      } 
Kann es sein, das hier ein RS232Buffer.clear() fehlt. Sonst wird doch bei jedem Schleifendurchlauf der RS232Buffer größer, oder?

Verfasst: 1. Februar 2008 15:32
von kuberka
Hi,

ich habe in mein RS232 ReadThread msleep(1) eingefügt und die Prozessorauslastung ist um 50% gesunken.

War ein super tipp danke.


Gruss

Torsten