Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Manage Qthread -resource creation and deletion
Forum Updated to NodeBB v4.3 + New Features

Manage Qthread -resource creation and deletion

Scheduled Pinned Locked Moved Solved General and Desktop
20 Posts 6 Posters 1.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    meganathan
    wrote on last edited by VRonin
    #1

    Hi,

    i have an class "FelixThread" that inherited from QThread.
    inside

    void FelixThread::run()
    {
    process = new QProcess();
            process->setWorkingDirectory(workingDir);
    
            mutex.lock();
    
            process->start(solverPath, QIODevice::ReadWrite|QIODevice::Append);
            process->waitForStarted();
            if(process->state() != QProcess::ProcessState::Running) {
                mutex.unlock();
                return;
            }
    
            bool bLocked = true;
            while(1)
            {
                process->waitForReadyRead(-1);
                QString str = process->readAllStandardOutput();
                if(str.contains("Main Menu"))
                  break;
    
                if(str.contains("Opening Materials"))
                {
                    bLocked = false;
                    mutex.unlock();
                }
            }
    
            if(bLocked)
             mutex.unlock();
    
            process->write("3\n");
            process->waitForReadyRead(-1);
    
            for(int i = 0; i < fileIndex; i++)
    		{
    			QString name = QString("%1%2").arg(iterationName).arg(i+1);
    			if(numNodes <= 80000)
    			  name = iterationName;
    
    			process->write((name + ".felix\n").toAscii().data());
    		}
    	    
    		process->write("\n");
    
    		while(1)
            {
                process->waitForReadyRead(-1);
                QString str = process->readAllStandardOutput();
                if(str.contains("Main Menu"))
                  break;
            }
    
           process->write("5\n");
           process->waitForFinished(-1);
    
           delete process
    }
    

    Creation:

    FelixThread *thread = new FelixThread(dir.path(), ("\"" + QDir::currentPath() + "\\Felix_Strain.exe\""), iteration.name, fileIndex, numNodes, felixMutex);
    
    threads.append(thread);
    thread->start();
    

    i will create many thread based on value of felixThread->idealThreadCount() -2. Let's say if i have 20 loadcases to solve i will create 20 threads based on ideal thread count. if idealthreadcount is 5, the execution is divided to 4 batch in each batch 4 thread is created.

    The problem is, in one machine whose ideal thread count is 32, so all the 20 loadcases will be run on 20 different threads at same time. but after 10 loadcases or 13 loadcases ,it hangs after that. But few times it can able to solve all the loadcases.

    i Even tried to reduce the idealthreadcount to 8 and 10 but the result is same, it stops after 11 or 13 loadcases.

    In run(), am i allocating the resource to thread correctly or i need to change. Please help me

    1 Reply Last reply
    0
    • H Offline
      H Offline
      Heb8
      Banned
      wrote on last edited by Heb8
      #2
      This post is deleted!
      M 1 Reply Last reply
      3
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by VRonin
        #3

        You are using a thread just because you are obsessing over using syncronous operations of QProcess (i.e. waitFor methods). This should be all handled in the spawning (main?) thread connecting slots to the appropriate QProcess signals: https://doc.qt.io/qt-5/qprocess.html#signals

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        5
        • H Heb8

          This post is deleted!

          M Offline
          M Offline
          meganathan
          wrote on last edited by
          #4

          @heb8 Tried with QtConcurrent map method to create number of threads, but few times it doesn't create thread after solving like 18 loadcases and sometimes, it strucks at 15 loadcases

          jsulmJ 1 Reply Last reply
          0
          • M meganathan

            @heb8 Tried with QtConcurrent map method to create number of threads, but few times it doesn't create thread after solving like 18 loadcases and sometimes, it strucks at 15 loadcases

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @meganathan As @VRonin said: why do you use threads to use QProcess?! There is no need to do so.
            QProcess provides asynchronous API, use it instead of implementing work-arounds to use the synchronous one...

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            5
            • M Offline
              M Offline
              meganathan
              wrote on last edited by
              #6

              If i don't use QThread to solve the loadcases, at single point of time only one loadcase would be solved and makes execution time to take longer. Please suggest how can i use Qprocess with threads correctly or any other approach to solve

              1 Reply Last reply
              0
              • Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @meganathan said in Manage Qthread -resource creation and deletion:

                at single point of time only one loadcase would be solved

                No it is not correct! As @jsulm already told you the QProcess stuff is async so you can start as much QProcess instances as you want in your main thread and you'll get a signal when each of them is finished.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                4
                • M Offline
                  M Offline
                  meganathan
                  wrote on last edited by
                  #8

                  Ok thanks,..i will try it out

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    meganathan
                    wrote on last edited by VRonin
                    #9

                    i tried with asynchronous processes approach , but with that please help me with how to handle the write and wait appropriately.
                    With the below approach i can able to run only one Qprocess, remaining gets struct.

                    for(int i=0;i<8;i++)
                    	{
                    		stream << "started thread:" << i;
                    		process = new QProcess();
                    		process->setWorkingDirectory("C:\\Users\\H336803\\Documents\\Visual Studio 2005\\Projects\\QthreadTest\\QthreadTest\\output\\"+QString::number(i));
                    		process->setObjectName("Loadcase"+QString::number(i));
                    		connect(process,SIGNAL(started()),this,SLOT(processStarted()));
                    		connect(process,SIGNAL(finished(int)),this,SLOT(processFinished(int)));
                    		connect(process, SIGNAL(finished(int)), process, SLOT(deleteLater()));
                    		connect(process,SIGNAL(error()),this,SLOT(processError()));
                    		process->start("felix2.exe", QIODevice::ReadWrite|QIODevice::Append);
                    
                    }
                    void QthreadTest::processStarted()
                    {
                    	QMutex mutex;
                    	QString curr = process->objectName();
                    	stream << ", Process name" << curr;
                    
                    	connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(readInput()));
                    	}
                    
                    void QthreadTest::readInput()
                    {
                    		QString str = process->readAllStandardOutput();
                    		if(str.contains("Main Menu"))
                    		{
                    			 process->write("3\n");
                    			 connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(waitforWriting()));
                    		}
                    }
                    void QthreadTest::waitforWriting()
                    {
                    	process->write("LoadCase1.felix\n");
                    	process->write("\n");
                    	
                    	connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(readInput1()));
                    
                    }
                    
                    void QthreadTest::readInput1()
                    {
                    		QString str = process->readAllStandardOutput();
                    		
                    		if(str.contains("Main Menu"))
                    		{
                    			 process->write("5\n");
                    			 connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(processFin()));
                    		}
                    }
                    
                    jsulmJ 1 Reply Last reply
                    0
                    • M meganathan

                      i tried with asynchronous processes approach , but with that please help me with how to handle the write and wait appropriately.
                      With the below approach i can able to run only one Qprocess, remaining gets struct.

                      for(int i=0;i<8;i++)
                      	{
                      		stream << "started thread:" << i;
                      		process = new QProcess();
                      		process->setWorkingDirectory("C:\\Users\\H336803\\Documents\\Visual Studio 2005\\Projects\\QthreadTest\\QthreadTest\\output\\"+QString::number(i));
                      		process->setObjectName("Loadcase"+QString::number(i));
                      		connect(process,SIGNAL(started()),this,SLOT(processStarted()));
                      		connect(process,SIGNAL(finished(int)),this,SLOT(processFinished(int)));
                      		connect(process, SIGNAL(finished(int)), process, SLOT(deleteLater()));
                      		connect(process,SIGNAL(error()),this,SLOT(processError()));
                      		process->start("felix2.exe", QIODevice::ReadWrite|QIODevice::Append);
                      
                      }
                      void QthreadTest::processStarted()
                      {
                      	QMutex mutex;
                      	QString curr = process->objectName();
                      	stream << ", Process name" << curr;
                      
                      	connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(readInput()));
                      	}
                      
                      void QthreadTest::readInput()
                      {
                      		QString str = process->readAllStandardOutput();
                      		if(str.contains("Main Menu"))
                      		{
                      			 process->write("3\n");
                      			 connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(waitforWriting()));
                      		}
                      }
                      void QthreadTest::waitforWriting()
                      {
                      	process->write("LoadCase1.felix\n");
                      	process->write("\n");
                      	
                      	connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(readInput1()));
                      
                      }
                      
                      void QthreadTest::readInput1()
                      {
                      		QString str = process->readAllStandardOutput();
                      		
                      		if(str.contains("Main Menu"))
                      		{
                      			 process->write("5\n");
                      			 connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(processFin()));
                      		}
                      }
                      
                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @meganathan said in Manage Qthread -resource creation and deletion:

                      readyReadStandardOutput

                      Why do you connect this signal to three different slots? All of them will be executed. You can handle everything with one slot, or disconnect slots you don't need anymore.

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      1
                      • M Offline
                        M Offline
                        meganathan
                        wrote on last edited by
                        #11

                        since can't use waitforReadReady() which blocks every qprocess

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          Hi,

                          An additional note, in your loop you are overwriting the same variable name process over and over again. This is not a good idea since you re-use it later on.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          4
                          • M Offline
                            M Offline
                            meganathan
                            wrote on last edited by
                            #13

                            How can i use asynchronous Interactive QProcess withour waitforReadyRead(-1)? .Please help me how i can do it

                            jsulmJ 1 Reply Last reply
                            0
                            • M meganathan

                              How can i use asynchronous Interactive QProcess withour waitforReadyRead(-1)? .Please help me how i can do it

                              jsulmJ Offline
                              jsulmJ Offline
                              jsulm
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              @meganathan said in Manage Qthread -resource creation and deletion:

                              How can i use asynchronous Interactive QProcess withour waitforReadyRead(-1)?

                              Using signals slots, but don't connect 3 different slots to same signal as I stated above.

                              https://forum.qt.io/topic/113070/qt-code-of-conduct

                              1 Reply Last reply
                              5
                              • VRoninV Offline
                                VRoninV Offline
                                VRonin
                                wrote on last edited by
                                #15

                                You don't need to wait for writing, std i/o is buffered so if you don't care about the state you can write multiple things to the process at once and the process will receive them and use them in order without you needing anything else

                                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                ~Napoleon Bonaparte

                                On a crusade to banish setIndexWidget() from the holy land of Qt

                                1 Reply Last reply
                                3
                                • M Offline
                                  M Offline
                                  meganathan
                                  wrote on last edited by
                                  #16

                                  i made the changes as requested, but am i facing problem to identify which process is started and which process has emitted readReadyStandardOutput().

                                  void QthreadTest::startThread()
                                  {
                                  processFinish =0;
                                  for(int i=0;i<8;i++)
                                  {
                                  stm << "started thread:" << i;
                                  process = new QProcess();
                                  listOfProcess->append(process);
                                  }
                                  startProcesses();
                                  }

                                  void QthreadTest::startProcesses()
                                  {
                                  for(int i=0;i<listOfProcess->size();i++)
                                  {
                                  listOfProcess[i]->setWorkingDirectory("C:\Users\H336803\Documents\Visual Studio 2005\Projects\QthreadTest\QthreadTest\output\"+QString::number(i));
                                  listOfProcess[i]->setObjectName("Loadcase"+QString::number(i));
                                  connect(listOfProcess[i],SIGNAL(started()),this,SLOT(processStarted()));
                                  connect(listOfProcess[i],SIGNAL(finished(int,QProcess::ExitStatus exitStatus)),this,SLOT(processFinished(int,QProcess::ExitStatus)));
                                  connect(listOfProcess[i],SIGNAL(readyReadStandardOutput()),this,SLOT(readInput()));
                                  connect(listOfProcess[i],SIGNAL(error()),this,SLOT(processError()));

                                  	listOfProcess[i]->start("felix2.exe", QIODevice::ReadWrite);
                                  }
                                  

                                  }

                                  void QthreadTest::readInput()
                                  {
                                  QString str = process->readAllStandardOutput(); // need help here

                                  	if(str.contains("Main Menu"))
                                  	{			
                                  		 process->write("3\n");			
                                  	}
                                  	else if(str.contains("Enter"))
                                  	{
                                  		process->write("LoadCase1.felix\n");
                                  		process->write("\n");
                                  	}
                                      else if(str.contains("Results"))
                                  	{
                                  		process->write("5\n");
                                  	}
                                  

                                  }

                                  As you can see in readInput() function , i coan't get which Qprocess is currently emitted readReadyStandardOuput() signal,
                                  Please help what i am doing wrong?

                                  jsulmJ 1 Reply Last reply
                                  0
                                  • M meganathan

                                    i made the changes as requested, but am i facing problem to identify which process is started and which process has emitted readReadyStandardOutput().

                                    void QthreadTest::startThread()
                                    {
                                    processFinish =0;
                                    for(int i=0;i<8;i++)
                                    {
                                    stm << "started thread:" << i;
                                    process = new QProcess();
                                    listOfProcess->append(process);
                                    }
                                    startProcesses();
                                    }

                                    void QthreadTest::startProcesses()
                                    {
                                    for(int i=0;i<listOfProcess->size();i++)
                                    {
                                    listOfProcess[i]->setWorkingDirectory("C:\Users\H336803\Documents\Visual Studio 2005\Projects\QthreadTest\QthreadTest\output\"+QString::number(i));
                                    listOfProcess[i]->setObjectName("Loadcase"+QString::number(i));
                                    connect(listOfProcess[i],SIGNAL(started()),this,SLOT(processStarted()));
                                    connect(listOfProcess[i],SIGNAL(finished(int,QProcess::ExitStatus exitStatus)),this,SLOT(processFinished(int,QProcess::ExitStatus)));
                                    connect(listOfProcess[i],SIGNAL(readyReadStandardOutput()),this,SLOT(readInput()));
                                    connect(listOfProcess[i],SIGNAL(error()),this,SLOT(processError()));

                                    	listOfProcess[i]->start("felix2.exe", QIODevice::ReadWrite);
                                    }
                                    

                                    }

                                    void QthreadTest::readInput()
                                    {
                                    QString str = process->readAllStandardOutput(); // need help here

                                    	if(str.contains("Main Menu"))
                                    	{			
                                    		 process->write("3\n");			
                                    	}
                                    	else if(str.contains("Enter"))
                                    	{
                                    		process->write("LoadCase1.felix\n");
                                    		process->write("\n");
                                    	}
                                        else if(str.contains("Results"))
                                    	{
                                    		process->write("5\n");
                                    	}
                                    

                                    }

                                    As you can see in readInput() function , i coan't get which Qprocess is currently emitted readReadyStandardOuput() signal,
                                    Please help what i am doing wrong?

                                    jsulmJ Offline
                                    jsulmJ Offline
                                    jsulm
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #17

                                    @meganathan You can use new connect syntax and lambdas, like:

                                    connect(listOfProcess[i],&QPRocess::started, [listOfProcess[i], this] { ... });
                                    

                                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                                    M 1 Reply Last reply
                                    2
                                    • jsulmJ jsulm

                                      @meganathan You can use new connect syntax and lambdas, like:

                                      connect(listOfProcess[i],&QPRocess::started, [listOfProcess[i], this] { ... });
                                      
                                      M Offline
                                      M Offline
                                      meganathan
                                      wrote on last edited by
                                      #18

                                      @jsulm i am using Qt 4.8.5 ,this syntax won't work i guess

                                      jsulmJ 1 Reply Last reply
                                      0
                                      • M meganathan

                                        @jsulm i am using Qt 4.8.5 ,this syntax won't work i guess

                                        jsulmJ Offline
                                        jsulmJ Offline
                                        jsulm
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #19

                                        @meganathan said in Manage Qthread -resource creation and deletion:

                                        this syntax won't work i guess

                                        True
                                        Then take a look at https://doc.qt.io/qt-5/qsignalmapper.html

                                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                                        1 Reply Last reply
                                        2
                                        • M Offline
                                          M Offline
                                          meganathan
                                          wrote on last edited by
                                          #20

                                          Thanks this works

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved