Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Multiple threads calling same function



  • I am using one function of the class (Test) to run in multiple threads and provide unique output for each execution. MainClass is calling class and Test is worker class. I have following way of implementation:

     void MainClass::getCommandOutput(const QString &commandType)
    {
      Test *test = new Test();
      QThread *commandExecutionThread = new QThread;
      commandExecutionThread->setObjectName("comamndExecutionThread" + QString(QRandomGenerator::global()->generate()));
      test->moveToThread(commandExecutionThread);
    
      connect(commandExecutionThread, SIGNAL(finished()), commandExecutionThread, SLOT(deleteLater()));
      connect(commandExecutionThread, SIGNAL(finished()), test, SLOT(deleteLater()));
      connect(test, SIGNAL(signal_executeCommand(const QString &)), test, SLOT(slot_executeCommand(const QString &)));
      connect(test, SIGNAL(signal_commandExecutionResultRead(const QString &, const QString &)), this, SLOT(slot_commandExecutionResultRead(const QString &, const QString &)));
      commandExecutionThread->start();
      emit test->signal_executeCommand(commandType);
    }
    

    and my worker class has multiple functions out of which I just want this function to run in this thread:

    void Test::slot_executeCommand(const QString &commandType)
    {
        const QString commandOutput = "";
        // do something using local variables only
        commandOutput.append(/*executed data received from server while using libssh2*/);
        emit signal_commandExecutionResultRead(comamndType, commandOutput);
        
        if (QApplication::instance()->thread() != QThread::currentThread() && QThread::currentThread()->isRunning())
        {
            QThread::currentThread()->quit();
        }
    }
    

    Now issue is, as getCommandOutput is getting called multiple times in asynchronous manner. Expectation is it will run slot_executeCommand under separate and unique thread so commandOutput must be unique. But sometimes I get commandOutput result appended with previous or ongoing execution data. I feel I am using thread in all wrong way. Any help is appreciated. Thank you.

    Note: I have multiple functions in Test class and I am running some of them from Mainclass in similar way how I mentioned above by creating separate object of Test class.


  • Lifetime Qt Champion

    Hi,

    The first question is: why do you need threads at all for your tests ?
    What is the structure of your tests ?
    How are you getting the output of your test back ?



  • I am calling 200 commands, which are getting executing on linux server over ssh (10 commands/threads at once). I don't want them as a blocking call to my application so creating multiple threads and executing them simultaneously.
    I am receiving output back by connecting "signal_commandExecutionResultRead(const QString &commandType, const QString &commandOutput)" in "getCommandOutput" function of MainClass, where commandType is unique value.

    PS: Made those changes in my original question to make it more clear.


  • Lifetime Qt Champion

    Still no need to create threads here. Simply spawn some QProcesses and you're done.



  • Application requirement is not to use QProcess (we can't use ssh and scp) and use libssh2 libraries and its APIs to get libssh2 operations working.


  • Lifetime Qt Champion

    Then I would go with QtConcurrent - add all commands to a queue and let the worker do it's job.


  • Lifetime Qt Champion

    Looks like you are re-implementing tools that already exist for that purpose. Was tmux/xpanes considered ?

    In any case, before doing any threading, you should have a proper encapsulation for your connection and command sending. Once you have that you can start thinking about threads or maybe use QtConcurrent. It looks like you rather have lists of commands to send to machines. A bit like what ansible manages for you with its playbook.