PDA

View Full Version : Mutlithreading hangs gui



thahir1986
28th September 2010, 08:07
First of all , i need to tell I'm a very newb to qt.

I want to create a multithreading program for RingBuffer. I done it, but while the thread running it hangs the gui.

I call the two thread for read from and write on ringbuffer by the push button signal. While the thread process going on , i can't access the gui ..Is anything wrong in my program.

Below i paste my program. I have the ring Buffer as a seperate class file. If u want i will give that too..


//Header file


#ifndef RING_QTHREAD_H
#define RING_QTHREAD_H

#include <QWidget>
#include <QtGui>
#include <QThread>
#include <QMutex>

#include "ringBuffer.hh"

#define BUFF_SIZE 10

namespace Ui {
class Ring_Qthread;
}

class Ring_Qthread : public QWidget {
Q_OBJECT
public:
Ring_Qthread(QWidget *parent = 0);
~Ring_Qthread();


protected:
void changeEvent(QEvent *e);
bool eventFilter(QObject *, QEvent *);

private slots:
void slot_load_buffer();
void slot_start_process();
void slot_quite_me();

private:
Ui::Ring_Qthread *ui;

void fn_create_conn(void);

};

class Writer : public QThread
{
public:
Writer();
void run();
};

class Reader : public QThread
{
public:
Reader();
void run();
};

/*
* Start the Structure for input and output of RingBuffer.
*/

typedef struct struct_buff
{
int xval;
int yval;

float xtime;
float ytime;
}struct_buff_t;

/*
* End of strucutre.
*/


#endif // RING_QTHREAD_H



//Sourcefile...



#include "ring_qthread.h"
#include "ui_ring_qthread.h"



//Global Variables
struct_buff_t in_buff[BUFF_SIZE+1], out_buff[BUFF_SIZE+1];
QMutex mut_check;
QWaitCondition cond_check;
int i_return = 0;
long int i_tot_count = 0;
long int i_out_count = 0;
bool b_inp = false;
bool b_out = false;
//i_tot_count=i_out_count=0;


/*
* Start of Predefined Functions
*/

Ring_Qthread::Ring_Qthread(QWidget *parent) :
QWidget(parent),
ui(new Ui::Ring_Qthread)
{
ui->setupUi(this);
fn_create_conn();

}


Ring_Qthread::~Ring_Qthread()
{
delete ui;
}

void Ring_Qthread::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
switch (e->type())
{
qDebug() << "omg";
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}

/*
* End of Pre-defined Functions
*/


/*
* Event filter function for get call after mouse click on all buttons.
*/


bool Ring_Qthread::eventFilter(QObject *_obj, QEvent *_event)
{

if(_event->type() == QEvent::MouseButtonPress)// && ((QMouseEvent*)_event)->button() == Qt::LeftButton)
{
qDebug() << "This is Event filter to help u\n";
if(_obj->objectName() == "btn_quit")
{
qDebug() << "btn_quit";
emit slot_quite_me();
}
else if (_obj->objectName() == "btn_process")
{
qDebug() << "btn_process";
emit slot_start_process();
}
else if (_obj->objectName() == "btn_load")
{
qDebug() << "btn_load";
emit slot_load_buffer();
}
return true;

}
else
return false;
}


/*
* Start of create connections Functions.
*/
void Ring_Qthread::fn_create_conn()
{

//Use the below commented code if u r gonna use slot and signals

connect(ui->btn_load, SIGNAL(clicked()), this, SLOT(slot_load_buffer()));
connect(ui->btn_process, SIGNAL(clicked()), this, SLOT(slot_start_process()));
connect(ui->btn_quit, SIGNAL(clicked()), this, SLOT(slot_quite_me()));

/*
ui->btn_process->installEventFilter(this);
ui->btn_quit->installEventFilter(this);
ui->btn_load->installEventFilter(this);
*/
}

/*
* End of Create connections Functions
*/

/*
* Start of Slot Functions.
*/

void Ring_Qthread::slot_load_buffer()
{
for (int i=0; i<BUFF_SIZE; ++i)
{
in_buff[i].xval = rand() % 10;
in_buff[i].yval = rand() % 10;

in_buff[i].xtime = rand() % 500;
in_buff[i].ytime = rand() % 500;
}
in_buff[BUFF_SIZE].xval = -1;
in_buff[BUFF_SIZE].yval = -1;

in_buff[BUFF_SIZE].xtime = -1;
in_buff[BUFF_SIZE].ytime = -1;

QFile *in_file;
in_file = new QFile("input_buffer.txt");
if(!in_file->open(QIODevice::WriteOnly | QIODevice::Text))
qDebug() << "Error in open the input Buffer file";
QTextStream stream_in(in_file);
for (int j=0;j<=BUFF_SIZE;j++)
{
stream_in << in_buff[j].xval << " " << in_buff[j].yval << " " << in_buff[j].xtime << " " << in_buff[j].ytime << "\n";

}

}

void Ring_Qthread::slot_start_process()
{

Writer writer1;
Reader reader1;

writer1.start();
reader1.start();

writer1.wait();
reader1.wait();

return (void)NULL;



}

void Ring_Qthread::slot_quite_me()
{
exit(0);
}

///////////////////////////////////////////////////////////////
/*
* Start of Class Writer Functions.
*/

Writer::Writer() : QThread()
{
//Code if u want.
}

void Writer::run()
{
//i_return = 3;
for (int j=0; j<=BUFF_SIZE; j++)
{
qDebug() << in_buff[j].xval << " " << in_buff[j].yval << " " << in_buff[j].xtime << " " << in_buff[j].ytime << "\n";
}

forever
{
mut_check.lock();
if (i_return !=4)
{
i_return = fn_process(1, &in_buff[i_tot_count].xval, &in_buff[i_tot_count].yval, &in_buff[i_tot_count].xtime, &in_buff[i_tot_count].ytime);
if (i_return == 4)
{
cond_check.wait(&mut_check);
}
else if (i_return == 2)
{
//qDebug() << "Writer \n";

i_tot_count++;
//cond_check.wait(&mut_check);
}
if(in_buff[i_tot_count-1].xval == -1)
b_inp = true;
}
mut_check.unlock();

if (b_inp && b_out)
return (void) NULL;
}

}

/*
* End of Class Writer Functions.
*/



///////////////////////////////////////////////////////////////
/*
* Start of Reader Class Functions
*/

Reader::Reader() : QThread()
{
//Code if u want
}

void Reader::run()
{
forever
{
mut_check.lock();
if(i_return !=1)
{
i_return = fn_process(2, &out_buff[i_out_count].xval, &out_buff[i_out_count].yval, &out_buff[i_out_count].xtime, &out_buff[i_out_count].ytime);

if(i_return == 3)
{
//qDebug() << "reader\n";

i_out_count++;
//cond_check.wakeOne();
}
else if (i_return == 1)
{
qDebug() << "go man go\n";
cond_check.wakeOne();
}
if (out_buff[i_out_count-1].xval == -1)
b_out = true;
}
mut_check.unlock();

if (b_inp && b_out)
{
qDebug() << "\nOutPut man.\n";
for (int j=0; j<=BUFF_SIZE; j++)
{
qDebug() << out_buff[j].xval << " " << out_buff[j].yval << " " << out_buff[j].xtime << " " << out_buff[j].ytime << "\n";
}
return (void)NULL;
}
}
}

/*
* End of Reader Class functions.
*/

///////////////////////////////////////////////////////////////

tbscope
28th September 2010, 08:49
Try debugging your program. Set some breakpoints and see where it loops infinitly.

What the #@* is this?

return (void)NULL;

By the way: asking the same question on multiple forums is considered rude by me.

wysota
28th September 2010, 10:10
You are starting a thread and immediately calling wait() which blocks the calling thread (your gui thread) until the thread it is waiting for exits.