PDA

View Full Version : signal not emitting from run() in multi-threaded app



naturalpsychic
25th January 2011, 14:34
signal not emitting from run() in multi-threaded app:

here is my code bits:

_threadCopy.cpp
void ThreadCopy::run()
{

ThreadCopy::fileObj.copy();


}

fileObj is object of _File and copy is its function, any signal outside Copy method is being emitted but any signal inside copy method / function, is not emiited...
e.g, updateProgress() signal is not emiited which is inside copy() with following code:

_file.cpp
emit updateProgress(currentSize);

i tried to make my question concise thats why didn't put up whole code but i am sure there is nothing wrong with code since it was working fine before i ran it without QThread implementation.

i am sure i am missing some information about QThread that i need to know....also i tried to uuse moveToThread with following code

main.cpp:

ThreadCopy *t;
_File* F;
t=new ThreadCopy(*F,(fcpy.count()));
F->moveToThread(t);
t->start();
t->wait();

any help?thanks

Lesiok
25th January 2011, 14:42
Signals are emitted but not delivered because Yours ThreadCopy::run() blocks event que. Just look at QThread how run method in example class is constructed.

naturalpsychic
25th January 2011, 15:04
i dont get it. How is my event being blocked?

tbscope
25th January 2011, 15:39
You do not have any event loop in your thread.
See the exec() function.

Lesiok
25th January 2011, 15:43
Not event but event dispatcher. Every thread should have an working event loop started by QThread::exec method. You don't start event loop in Yours run method. Your problem is an classic example of problem described in this article (http://doc.qt.nokia.com/qq/qq27-responsive-guis.html).

msdark
7th April 2011, 20:22
(sorry for my english)
I have the same problem .. signal is not emitted ...i know that i need to add a event loop to the app but i don't know where and how ..

My app is a producer/consumer problem that i solve with WaitConditions and a Circular Buffer.. So i have a main Thread and two sub-threads Producer and Consumer
i the code the Producer emit a signal that i need to use to update some information to show.

This is a console app.

Some snippet of the code:

ProducerThread


ProcessingThread::ProcessingThread(FrameBuffer *imageBuffer, double inputSourceWidth, double inputSourceHeight,QObject *parent) :QThread(parent){
this->buffer = imageBuffer;
this->stopped = false;
}


void ProcessingThread::run(){

while(1){
// Stop thread if stopped=TRUE //
stoppedMutex.lock();
if (stopped)
{
stopped=false;
stoppedMutex.unlock();
break;
}
stoppedMutex.unlock();
// Get frame from queue
this->currentFrame = buffer->getFrame();
if(this->currentFrame.empty()==false){
//Do the heavy work
emit newFrame();
}else{
qDebug()<<"Se recibio un frame NULL";
}
}

qDebug()<<"Deteniendo el procesado";
}


The ConsumerThread


ConsumerThread::ConsumerThread(FrameBuffer *buffer, int deviceNumber):QThread(), imageBuffer(buffer){
// Open camera
capture = VideoCapture(deviceNumber);
// Initialize variables
stopped=false;
}

void ConsumerThread::run()
{
while(1)
{
/////////////////////////////////
// Stop thread if stopped=TRUE //
/////////////////////////////////
stoppedMutex.lock();
if (stopped)
{
stopped=false;
stoppedMutex.unlock();
break;
}
stoppedMutex.unlock();
/////////////////////////////////
/////////////////////////////////

// Capture and add frame to buffer
//....
//....

}
qDebug() << "Stopping capture thread...";
} // run()


So i have a Controller class to get access to this threads
and i Show class to execute this using the controller
The Show class:


Show::Show(QObject *parent) :QObject(parent){
qDebug()<<"Iniciando..";
controlador = new Controlador(3,3,0);
}

void Show::start(){
qDebug()<"Start";
if(controlador->isCameraConnected()){
connect(controlador->processing,SIGNAL(newFrame()),this,SLOT(updateFram e()),Qt::QueuedConnection);
controlador->capture->start();
controlador->processing->start();
controlador->capture->wait();
controlador->processing->wait();
controlador->disconnectCamera();
}
}

void Show::updateFrame(){
qDebug()<<"Update Frame";
}




But the signal newFrame or is never emitted or the slot updataFrame don't receive the signal..

any idea???

tbscope
8th April 2011, 06:28
Signals and slots accross threads make use of events.
To make use of events, you must run an event loop in your thread.
To run an event loop in your thread you must call the function exec() from within your thread (i.e. the run() function).

References:
http://doc.qt.nokia.com/4.7/qthread.html#exec
http://doc.qt.nokia.com/4.7/qthread.html
http://doc.qt.nokia.com/4.7/threads.html