PDA

View Full Version : QThread - trying to kill a qthread synchronously



lhdamiani
19th February 2014, 15:50
I've been trying to do this for a couple of days, following examples and forums tips.

The situation is the following: I have a GUI that freezes when i call a heavy mathematical function, this way, what i want is to dispatch this heavy math function to a thread and keep the GUI responsive and so on. So far, i got this going and its ok.

The problem starts because i need to have a 'kill button' (the user might just want to kill it since he can sometimes just change parameters and start a new one after realizing things are not going the way he wanted). I also know that this is not so recommended, the thread should never be killed/terminate - it should terminate itself - the problem here is that this heavy mathematical function isn't mine. It's legacy code and I don't have permissions to change anything inside this function.

What i have so far:

1) QThread and Worker


thread = new QThread();
worker = new Worker();
worker->moveToThread(thread);
connect(worker, SIGNAL(workRequested()), thread, SLOT(start()));
connect(thread, SIGNAL(started()), worker, SLOT(doWork()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection);

2)
...
...

worker->abort();
thread->wait();
worker->requestWork();

...
...

3)

void Worker::abort()
{
mutex.lock();
if (_working) {
_abort = true;
qDebug()<<"Request worker aborting in Thread "<<thread()->currentThreadId();
}
mutex.unlock();
}



void Worker::requestWork()
{
mutex.lock();
_working = true;
_abort = false;
qDebug()<<"Request worker start in Thread "<<thread()->currentThreadId();
mutex.unlock();

emit workRequested();
}

void Worker::doWork()
{
qDebug()<<"Starting worker process in Thread "<<thread()->currentThreadId();


qDebug() << "get current process" << ::GetCurrentProcessId();

threadId = thread()->currentThreadId();

threadForTheSimulator = thread();


mutex.lock();
bool abort = _abort;
mutex.unlock();


while (abort == false)
{
// Checks if the process should be aborted
mutex.lock();
abort = _abort;
mutex.unlock();

// heavy mathematical function
runCSimulator(numberOfArguments,contentOfArgs);


}

// Set _working to false, meaning the process can't be aborted anymore.
mutex.lock();
_working = false;
mutex.unlock();

qDebug()<<"Worker process finished in Thread "<<thread()->currentThreadId();

emit finished();
}

4) the heavy computation functions is named runCSimulator(int, args)... obvisously since my function's thread doenst has a main loop or event this 'abort' function is never called.. it jumps into the function and never comes back from there.. therefore, what i think i need is a function connected with the GUI button that will cancel :

// function triggered with the terminate button
void Worker::doTerminate()
{
// here should go the code to kill the thread started
// The problem here is that when i try to put the code
// to terminate or quiot here, they are assynchronous.
// I need something synchrnous that whenever the user
// clicks the terminateButton it will shut down this thread.
}


Any help is really appreciated!

Thanks a LOT!

anda_skoa
19th February 2014, 20:44
The problem starts because i need to have a 'kill button' (the user might just want to kill it since he can sometimes just change parameters and start a new one after realizing things are not going the way he wanted). I also know that this is not so recommended, the thread should never be killed/terminate - it should terminate itself - the problem here is that this heavy mathematical function isn't mine. It's legacy code and I don't have permissions to change anything inside this function.

Then you need to run that in a separate process.
Child processes can be killed without negatively affecting the parent process.

Cheers,
_