Qt console application leaves terminal open on termination
-
@jsulm ,@Kent-Dorfman , now that I've fixed the launch function it works perfectly and when the main application is closed all the child processes automatically close, I am getting the following messages in the Application Output which are odd because despite the messages the child process is launched and running:
W00000000000000000014:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000015:(Parent is QProcess(0x101f31360), parent's thread is QThread(0x101f05f40), current thread is clsThread(0x120d05ff0) W00000000000000000016:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000017:(Parent is QProcess(0x101f31360), parent's thread is QThread(0x101f05f40), current thread is clsThread(0x120d05ff0) W00000000000000000018:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000019:(Parent is QProcess(0x101f31360), parent's thread is QThread(0x101f05f40), current thread is clsThread(0x120d05ff0) W00000000000000000020:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000021:(Parent is QProcess(0x101f31360), parent's thread is QThread(0x101f05f40), current thread is clsThread(0x120d05ff0) W00000000000000000022:QObject::connect: Cannot queue arguments of type 'QProcess::ProcessState' W00000000000000000023:(Make sure 'QProcess::ProcessState' is registered using qRegisterMetaType().) W00000000000000000024:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000025:(Parent is QProcess(0x101f31360), parent's thread is QThread(0x101f05f40), current thread is clsThread(0x120d05ff0) D00000000000000000026:L00000053Fsimon.js[static bool clsMainWnd::blnLaunch]:
@SPlatten said in Qt console application leaves terminal open on termination:
Cannot create children for a parent that is in a different thread.
Check your thread usage (do not use an object created in another thread as parent). The warning tells you what is wrong. Also, why do you use threads? QProcess is already asynchronous...
-
@SPlatten said in Qt console application leaves terminal open on termination:
Cannot create children for a parent that is in a different thread.
Check your thread usage (do not use an object created in another thread as parent). The warning tells you what is wrong. Also, why do you use threads? QProcess is already asynchronous...
-
@jsulm , the threads are in the main application, the main application is an engine which has specific functionality, the threads are used to maintain asynchronous communication between the main application and the modules.
@SPlatten said in Qt console application leaves terminal open on termination:
the threads are used to maintain asynchronous communication between the main application and the modules.
As a said: QProcess is already asynchronous. Why do you think you need threads.
And you you think you really need thread then check your implementation: you are doing something wrong with thread affinity. -
@SPlatten said in Qt console application leaves terminal open on termination:
the threads are used to maintain asynchronous communication between the main application and the modules.
As a said: QProcess is already asynchronous. Why do you think you need threads.
And you you think you really need thread then check your implementation: you are doing something wrong with thread affinity. -
@jsulm, my understanding is that QProcess is used to launch separate processes which is find for the modules, however for general multi-tasking in the main application which isn't dependant on other processes thats where threads are used.
-
@jsulm , its a bit like a web-server, multiple clients, each client (module) does not monopolise the application by holding up communications, so to keep it as responsive as possible each client gets it's own thread.
@SPlatten , I've re-written the launch function:
QProcess* clsScriptHelper::pLaunch(QString strApp, QStringList& slstArgs) { QString strFullPath(clsDebugService::strGetUserFolder(strApp)); qdbg() << "Checking for PID for: " << strFullPath; QProcess* pModule = nullptr; qint64 int64PID; if ( blnGetPID(strFullPath, int64PID) == true ) { //Process already running, no action required } else { int intLastSep = strFullPath.lastIndexOf(QDir::separator()); qdbg() << "Process is NOT running, launching"; if ( intLastSep > 0 ) { QString strName = strFullPath.mid(intLastSep + 1) ,strPath = strFullPath.mid(0, intLastSep + 1); pModule = new QProcess(this); pModule->setArguments(slstArgs); pModule->setWorkingDirectory(strPath); pModule->setProgram(strName); pModule->start(); int64PID = pModule->processId(); if ( int64PID == 0 ) { delete pModule; pModule = nullptr; } } } if ( int64PID > 0 ) { qdbg() << "Process: " << strFullPath << " started, PID: " << QString::number(int64PID); } return pModule; }
This works a lot better and now the child process is terminated and the terminal window closes when the main application terminates, however I am still seeing in the Application Output:
W00000000000000000014:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000015:(Parent is clsScriptHelper(0x10320da10), parent's thread is QThread(0x10320aad0), current thread is clsThread(0x10325d1a0)
Is there any way to avoid/prevent this?
-
@SPlatten , I've re-written the launch function:
QProcess* clsScriptHelper::pLaunch(QString strApp, QStringList& slstArgs) { QString strFullPath(clsDebugService::strGetUserFolder(strApp)); qdbg() << "Checking for PID for: " << strFullPath; QProcess* pModule = nullptr; qint64 int64PID; if ( blnGetPID(strFullPath, int64PID) == true ) { //Process already running, no action required } else { int intLastSep = strFullPath.lastIndexOf(QDir::separator()); qdbg() << "Process is NOT running, launching"; if ( intLastSep > 0 ) { QString strName = strFullPath.mid(intLastSep + 1) ,strPath = strFullPath.mid(0, intLastSep + 1); pModule = new QProcess(this); pModule->setArguments(slstArgs); pModule->setWorkingDirectory(strPath); pModule->setProgram(strName); pModule->start(); int64PID = pModule->processId(); if ( int64PID == 0 ) { delete pModule; pModule = nullptr; } } } if ( int64PID > 0 ) { qdbg() << "Process: " << strFullPath << " started, PID: " << QString::number(int64PID); } return pModule; }
This works a lot better and now the child process is terminated and the terminal window closes when the main application terminates, however I am still seeing in the Application Output:
W00000000000000000014:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000015:(Parent is clsScriptHelper(0x10320da10), parent's thread is QThread(0x10320aad0), current thread is clsThread(0x10325d1a0)
Is there any way to avoid/prevent this?
@SPlatten said in Qt console application leaves terminal open on termination:
Is there any way to avoid/prevent this?
Yes, doing multithreading in a proper way. As I wrote before: you are doing something wrongly somewhere in your code. And the warning even tells you what: you are using an objects as parent for another object which lives in another thread.
You should read this: https://doc.qt.io/qt-5/qobject.html#thread-affinity -
@SPlatten said in Qt console application leaves terminal open on termination:
Is there any way to avoid/prevent this?
Yes, doing multithreading in a proper way. As I wrote before: you are doing something wrongly somewhere in your code. And the warning even tells you what: you are using an objects as parent for another object which lives in another thread.
You should read this: https://doc.qt.io/qt-5/qobject.html#thread-affinity@jsulm, the difficulty is that the method of calling the launch function is from an exported / exposed (not sure of correct terminology) API call from the C++ to JavaScript:
Q_INVOKABLE QJsonObject use(QJsonValue strModule);
In the JavaScript:
xmleng.use("mdFileIO");
Where xmleng is exposed to the JavaScript by the engine:
const QString strXMLEngine("xmleng"); if ( objGlobal.hasProperty(strXMLEngine) == false ) { clsScriptHelper* pScriptHlpr = clsScriptHelper::pobjGetInstance(); if ( pScriptHlpr != nullptr ) { QJSValue result = pobjScriptEng->newQObject(pScriptHlpr); objGlobal.setProperty(strXMLEngine, result); } }
The use function in C++:
/** * @brief clsScriptHelper::use * @param strModule : Name of the module to use * @return JSON object containing pass on when using the module */ QJsonObject clsScriptHelper::use(QJsonValue strModule) { clsXMLnode* pobjRoot = clsXMLnode::spobjGetRoot(); Q_ASSERT_X(pobjRoot!=nullptr, "clsScriptHelper::use" , "pobjRoot is NULL!"); QString strModulesPath = pobjRoot->strGetAttribute(clsXMLnode::mscszAttrModules) ,strModuleName = strModule.toString(); //Is module already loaded? mpModules::iterator itrModule; QJsonObject objModule; QStringList slstSlot; if ( clsScriptHelper::blnGetModule(strModuleName, &itrModule) == true ) { //Module already loaded, get the process id objModule = itrModule->second; } else { //Module not loaded yet, attempt to start the module QString strFullPath(strModulesPath + strModule.toString()); QStringList slstArgs; slstArgs << QString::number(clsSocketServer::mscuint16port); slstArgs << QString::number(clsSocketServer::uint16NextModulePort()); slstArgs << QString::number(QCoreApplication::applicationPid()); QProcess* pProcess; if ( (pProcess = pLaunch(strFullPath, slstArgs)) != nullptr ) { //Module has been successfully started, save its PID qint64 int64PID = pProcess->processId(); objModule.insert(clsJSON::mscszModule, strModule); objModule.insert(clsScriptHelper::mscszPID, QJsonValue(int64PID)); msmpModules.insert(std::make_pair(strModuleName, objModule)); //Register JSON decoders QString strKey(strModule.toString() + clsJSON::msccColon + QString(clsJSON::mscszCmdHB)); clsJSON::registerDecoder(strKey, blnDecodeHeartbeat); } } return objModule; }
-
@SPlatten said in Qt console application leaves terminal open on termination:
Is there any way to avoid/prevent this?
Yes, doing multithreading in a proper way. As I wrote before: you are doing something wrongly somewhere in your code. And the warning even tells you what: you are using an objects as parent for another object which lives in another thread.
You should read this: https://doc.qt.io/qt-5/qobject.html#thread-affinity