Solved Parent process, child process and QCoreApplication
-
@J-Hilk , Thank you, I literally just found the same on Google, implementing now.
-
@J-Hilk , I've implemented this:
QObject::connect(pParent, SIGNAL(aboutToQuit()), this, SLOT(onExitModule()));
And my slot:
void clsModHelper::onExitModule() { #ifdef DEBUG_LOG if ( mfpDbgLog != nullptr ) { fclose(mfpDbgLog); } #endif terminate(); }
However when the parent terminates the child process doesn't.
-
@SPlatten said in Parent process, child process and QCoreApplication:
connect
you should check the return value of that connect, AFAIK aboutToQuit is a signal of QCoreApplication only and I don't know what pParent is
-
@J-Hilk In the case where I am using it pParent is passed into the constructor and is the address of the core application:
QCoreApplication a(intArgc, parystrArgv); QCoreApplication::setApplicationName(clsModFileIO::scpszTitle()); clsModFileIO obj(&a, intArgc, parystrArgv);
Constructor:
clsModHelper::clsModHelper(QObject* pParent, int intArgc, char* parystrArgv[] ,const char* cpszTitle, double dblVersion) : QTcpSocket(pParent) , mdblVersion(dblVersion) , mfpDbgLog(nullptr) , mint64AppPID(QCoreApplication::applicationPid()) , mstrTitle(cpszTitle) , muint16ModulePort(0), muint16LauncherPID(0) , muint16XMLMPAMport(0) { if ( intArgc < CLA_LAUNCHER_PID ) { std::cout << "Insufficient arguments, aborting!" << std::endl; exit(EXIT_FAILURE); } if ( mspThis == nullptr ) { mspThis = this; } muint16XMLMPAMport = (quint16)atoi(parystrArgv[CLA_XMLMPAM_PORT]); muint16ModulePort = (quint16)atoi(parystrArgv[CLA_MODULE_PORT]); muint16LauncherPID = (quint16)atoi(parystrArgv[CLA_LAUNCHER_PID]); setSocketOption(QAbstractSocket::LowDelayOption, 1); //Connect up the signals QObject::connect(pParent, SIGNAL(aboutToQuit()), this, SLOT(onExitModule())); ...
-
@SPlatten Well, yes
but you pass on a QObject* and try to connect to a signal that a derived class has. That doesn't work out of the box.
Thats why I said you should check the return value of QObject::connect its false in this case.
And the "new" syntax would not compile.anyway,
either qobject_cast pParent to QCoreApllication or use the singleton getter functionqApp
or equivalentlyQCoreApplication::instance()
-
@J-Hilk , I've just changed the code to:
QCoreApplication* pCore = static_cast<QCoreApplication*>(pParent); QObject::connect(pCore, SIGNAL(aboutToClose()), this, SLOT(onExitModule()));
Has the signal been renamed because I didn't see aboutToQuit, only aboutToClose?
-
@SPlatten
AFAIK its quit
https://doc.qt.io/qt-5/qcoreapplication.html#aboutToQuitalso I said to use qobject_cast not static_cast 😕
https://doc.qt.io/qt-5/qobject.html#qobject_cast -
Using:
QCoreApplication* pCore = static_cast<QCoreApplication*>(pParent); QObject::connect(pCore, SIGNAL(aboutToQuit), this, SLOT(onExitModule()));
and the slot:
void clsModHelper::onExitModule() { #ifdef DEBUG_LOG if ( mfpDbgLog != nullptr ) { fclose(mfpDbgLog); } #endif terminate(); }
I just can't get it to work. The child process stays running.
-
@SPlatten said in Parent process, child process and QCoreApplication:
Has the signal been renamed because I didn't see aboutToQuit, only aboutToClose?
To avoid this kind of error, use new connect syntax. So signals/slots validity will be checked at compilation time!
//QCoreApplication* pCore = static_cast<QCoreApplication*>(pParent); auto pCore = qobject_cast<QCoreApplication*>(pParent); //QObject::connect(pCore, SIGNAL(aboutToClose()), this, SLOT(onExitModule())); QObject::connect(pCore, &QCoreApplication::aboutToQuit, this, &clsModHelper::onExitModule);
-
@SPlatten said in Parent process, child process and QCoreApplication:
I just can't get it to work. The child process stays running.
What is pParent? Why do you not use
pApp
orQCoreApplication::instance()
?QObject::connect(pApp, &QCoreApplication::aboutToQuit, this, &clsModHelper::onExitModule);
-
@KroMignon , because I didn't know it was there, just changed code to:
QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit ,this, &clsModHelper::onExitModule);
Still doesn't work.
-
@SPlatten said in Parent process, child process and QCoreApplication:
Still doesn't work
So, did you actually check whether the onExitModule slot was called?
-
@SPlatten said in Parent process, child process and QCoreApplication:
Still doesn't work.
What does not work?
The slot is not called or the instance does not stop? -
@jsulm , yes and it isn't.
-
@SPlatten than I would assume your application doesn't actually quit :P
call quit manually in a timer after x amount of seconds, to see if everything closes correctly
-
@SPlatten said in Parent process, child process and QCoreApplication:
According to the documentation, using start will cause the child process to close when the parent is closed, which is exactly the functionality I want. It did work then I think after I modified the child to use QCoreApplication it has stopped working, in that when the parent process is terminated, the child process keeps running.
I'm going to throw my 2 cents in. Child process exiting when parent process exits --- so long as not detached, and child does not do something in its start up code to prevent it --- is an OS thing, not a Qt/C++ thing. So I would expect it to exit when parent exits, regardless of
QCoreApplication
or otherwise.[*]Are you sure (I mean 100%, guaranteed, you'll stake your grandmother on it) your parent process is exiting? For example, if it doesn't have a UI you won't get the default "exit app on last window closed" behaviour....
[*] EDIT I'm rethinking my claim/stance on this, OS-wise. It's more complex than I recalled. Luckily, I don't have any grandmother to stake on this statement, though I may be 2 cents poorer....
-
@JonB , It doesn't the process was launched using QProcess and the start method, I stopped the process that launched the child by closing all the windows. I then checked the processes running using:
ps -A
I can see the child is still running. I also attached to the child process using Qt Creator and put a break point in the onExitModule slot, it never gets there.
-
@SPlatten said in Parent process, child process and QCoreApplication:
I stopped the process that launched the child by closing all the windows.
I don't understand. You said it's now a
QCoreApplication
...Oh, it's the child which is the
QCoreApplication
, not the parent?I stopped the process that launched the child by closing all the windows
Maybe. Nonetheless, verify that the parent really does exit? Verify its (the parent's) PID has gone?
I am lost. Could you please make clear which process(es) are
QCoreApplication
s and which areQApplication
s, out of your parent & children? Just simply & clearly.Now that I have withdrawn/reneged on my earlier post claiming that OS will terminate children on parent exit:
If your parent is a UI application, you should be able to get its
aboutToQuit()
, and forcibly kill any child processes. Why you should need to do that when you usedQProcess::start()
I'm not sure. -
@JonB To clarify, the child application main:
int main(int intArgc, char* parystrArgv[]) { QCoreApplication a(intArgc, parystrArgv); QCoreApplication::setApplicationName(clsModFileIO::scpszTitle()); clsModFileIO obj(&a, intArgc, parystrArgv); return a.exec(); }
The constructor for clsModFileIO:
clsModHelper::clsModHelper(QObject* pParent, int intArgc, char* parystrArgv[] ,const char* cpszTitle, double dblVersion) : QTcpSocket(pParent) , mdblVersion(dblVersion) , mfpDbgLog(nullptr) , mint64AppPID(QCoreApplication::applicationPid()) , mstrTitle(cpszTitle) , muint16ModulePort(0), muint16LauncherPID(0) , muint16XMLMPAMport(0) { if ( intArgc < CLA_LAUNCHER_PID ) { std::cout << "Insufficient arguments, aborting!" << std::endl; exit(EXIT_FAILURE); } if ( mspThis == nullptr ) { mspThis = this; } muint16XMLMPAMport = (quint16)atoi(parystrArgv[CLA_XMLMPAM_PORT]); muint16ModulePort = (quint16)atoi(parystrArgv[CLA_MODULE_PORT]); muint16LauncherPID = (quint16)atoi(parystrArgv[CLA_LAUNCHER_PID]); setSocketOption(QAbstractSocket::LowDelayOption, 1); //Connect up the signals QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit ,this, &clsModHelper::onExitModule); ...
-
@SPlatten
Your reply may have crossed with my update.-
I can now see that your child processes are clearly
QCoreApplication
. -
What is your parent application?
QApplication
orQCoreApplication
?
EDIT
No, no, what's this://Connect up the signals QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit ,this, &clsModHelper::onExitModule);
That is "about to quit" in the child. I thought you said you want to the parent to exit, and the children should exit at the same time, isn't that your whole question?
-