PDA

View Full Version : QThread: Destroyed while thread is still running



Shuchi Agrawal
22nd March 2007, 12:32
hi all,
i have problem on windows and linux too...
i have 2 threads consumer and producer.
but when i stop them or exit the application i get the following comments after execution:
Running...
QThread: Destroyed while thread is still running

QThread: Destroyed while thread is still running

QWaitCondition: Destroyed while threads are still waiting

---------------------- Exited normally ----------------------

this problem has already been discussed on the following thread but i cudnt find the solution of my prob acc to the solution given in this :
http://www.qtcentre.org/forum/f-qt-programming-2/t-qthreads-5969.html

Some code as :

Consumer.cpp
void Consumer::run()
{
j=0;
while(!flag_stop)
{
usedBytes.acquire();
write_str += buffer[j % 8096];
j++;
freeBytes.release();
emit disp(); // disp a slot of mainwindow.cpp
}
flag_stop = true;
}
Producer.cpp
void Producer::run()
{
i=0;
while(!flag_stop)
{
if(flag_read)
{
freeBytes.acquire();
int n = read_str.size();
buffer[i % 8096] = (*((read_str.toUtf8().constData())+(n-1)));
i++;
usedBytes.release();
flag_read = false;
}

}
flag_stop = true;
}

Mainwindow.cpp
...
connect(textEdit_1,SIGNAL(textChanged()),this,SLOT (read_send()));
connect(pushButton_14,SIGNAL(clicked()),this,SLOT( Start_Thread()));
connect(pushButton_15,SIGNAL(clicked()),this,SLOT( Stop_Thread()));
consumer = new Consumer();
producer = new Producer();
connect(consumer,SIGNAL(disp()),this,SLOT(receive_ write()));
...
void MainWindowImpl::Start_Thread()
{
producer->start();
consumer->start();
}
void MainWindowImpl::Stop_Thread()
{
flag_stop = true;
}
void MainWindowImpl::read_send()
{
read_str = textEdit_1->toPlainText();
flag_read = true;
}
void MainWindowImpl::receive_write()
{
textEdit_2->setText(write_str);
}
void MainWindowImpl::closeEvent(QCloseEvent *event)
{
flag_stop = true;
event->accept();
}
Can any1 please help me that where i am misleading and where i have taken wrong approach.
Thanks All...

wysota
22nd March 2007, 12:54
You should call QThread::wait() on both threads from within your main thread to make sure they stopped (in Stop_Thread).

Shuchi Agrawal
23rd March 2007, 04:38
when i do
void MainWindowImpl::Stop_Thread()
{
flag_stop = true;
producer->wait();
consumer->wait();
}
then, if i dont press "Stop Thread" botton then i get
"Running...
QWaitCondition: Destroyed while threads are still waiting"
and is i press stop thread button t hen the program doesnt respond.

Globalvar.h
#ifndef __GLOBALVAR_H__
#define __GLOBALVAR_H__
#include <QSemaphore>
#include <QString>
extern QSemaphore freeBytes;
extern QSemaphore usedBytes;
extern QString read_str, write_str;
extern bool flag_read,flag_write,flag_stop;
extern char buffer[8096];
#endif // __GLOBALVAR_H__

Globalvar.cpp
#include "globalvar.h"
char buffer[8096];
QSemaphore freeBytes(8096);
QSemaphore usedBytes;
QString read_str, write_str;
bool flag_read = false ,flag_write = false, flag_stop = false;

So can u plz help me out?
Thanks.

wysota
23rd March 2007, 06:36
Your application hangs because the threads are sleeping on their semaphores. You should first make sure the "flag_stop" will really stop them without making one of the threads sleep on its semaphore because of an empty/full buffer - if the "flag_stop" is set when the thread is already sleeping, it might never be woken up.

The bottom line is, you have to go through your synchronisation mechanism again and rethink/correct it.

For example this could work:

void MainWindowImpl::Stop_Thread()
{
flag_stop = true;
producer->release();
consumer->release();
producer->wait();
consumer->wait();
}

void Producer::run()
{
i=0;
while(!flag_stop)
{
if(flag_read)
{
freeBytes.acquire();
if(flag_stop) return;
int n = read_str.size();
buffer[i % 8096] = (*((read_str.toUtf8().constData())+(n-1)));
i++;
usedBytes.release();
flag_read = false;
}

}
flag_stop = true;
}

void Consumer::run()
{
j=0;
while(!flag_stop)
{
usedBytes.acquire();
if(flag_stop) return;
write_str += buffer[j % 8096];
j++;
freeBytes.release();
emit disp(); // disp a slot of mainwindow.cpp
}
flag_stop = true;
}

As for the other problem - make sure you call Stop_Thread() before closing the application.

Shuchi Agrawal
2nd April 2007, 08:31
Hi all,
i am still having the same problem. i am not that good in programming and thus i am unable to fix this small problem. Please i wil be greatful to all who can help me out.
I am not able to stop the threads. How to do it. The code is given in the .zip file.
1026
Thanks all.

wysota
2nd April 2007, 10:19
I guess you didn't try my solution...

Shuchi Agrawal
2nd April 2007, 10:47
I guess you didn't try my solution...
yes i do tried solution given by you, but the entire program hangs on clicking "stop thread" button.

void MainWindowImpl::Stop_Thread()
{ flag_stop = true;
freeBytes.release(); //QSemaphore freeBytes;
usedBytes.release(); //QSemaphore usedBytes;
producer->wait();
consumer->wait();
}
So can u tel me where i m doing wrong.i wil be greatful beause i am reallly stuck here.

wysota
2nd April 2007, 10:53
This is not what I suggested. I suggested checking the stop flag after going through the acquire call. The thing you do in your code snippet you pasted here does nothing. Many things can happen between release() and wait().

Shuchi Agrawal
3rd April 2007, 06:27
Thanks a lot Wysota. i solved the problem by taking the approach "Your application hangs because the threads are sleeping on their semaphores. You should first make sure the "flag_stop" will really stop them without making one of the threads sleep on its semaphore because of an empty/full buffer - if the "flag_stop" is set when the thread is already sleeping, it might never be woken up." - quoted by you. Thanks a lot :)