The following piece of code starts a process that takes one second to finish, and subsequently waits for that process to finish before exiting. For some reason, the following code hangs in p->waitForFinished()
even though the process did finish.
#include <QtCore/QProcess>
class A
{
public:
A():
p(0)
{
}
~A()
{
p->waitForFinished();
delete p;
}
void start()
{
p = new QProcess(0);
p->start("sleep 1");
}
QProcess *p;
};
int main(void)
{
static A a;
a.start();
return 0;
}
However, as soon as a
is not declared statically, but as follows:
A a;
the waitForFinished()
call succeeds. Is this a Qt bug, or is this expected behavour? My suspicion is that some kind of logic required to detect whether an application successfully finished is already destroyed once the destructor of A
is called.
You have tried to clean up the thread created by QProcess
two different ways at the same time, so this is a bug in your program.
You've detached the thread by returning from main
(which terminates all threads in the process, detaching them if they are joinable).
And you've cleaned up the QProcess
thread by joining it through waitForFinished
.
You can detach a thread or you can join it, but you can't do both, even indirectly. Apparently, the detach wins, and the join hangs.
Most likely this is because QProcess
uses its own termination signal rather than the one built into the threading library. So the return from main
terminates the thread before it can send that termination signal, leaving the waitForFinished
function to wait for a signal that will never be sent.
As a general rule, threads should not be created in constructors nor cleaned up in destructors. This is primarily because the timing of these operations requires more explicit control than is possible. And they should never be created before main
starts nor cleaned up after main
returns -- again because you need to control the context in which these things happen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With