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. To Pass object into Thread
Forum Updated to NodeBB v4.3 + New Features

To Pass object into Thread

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 2 Posters 1.3k 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.
  • A Offline
    A Offline
    Andrey Shmelew
    wrote on last edited by
    #1

    Hi!

    I have a MainWindow class that has 4 objects of ChannelOptions class. (They're input signal channels, each iof them has properties like signal type etc...).
    When the application is running, sometimes they may be changed:

    void MainWindow::OpenOptionsWindow()
    {
        Options *optionsobj = new Options;
        optionsobj->exec();
      
        channel1object.ReadSingleChannelOptionFromFile(1);
        channel2object.ReadSingleChannelOptionFromFile(2);
        channel3object.ReadSingleChannelOptionFromFile(3);
        channel4object.ReadSingleChannelOptionFromFile(4);
    
    void ChannelOptions::ReadSingleChannelOptionFromFile(int channel)
    {
        QFile infile(pathtofile + "options.txt");
        infile.open(QIODevice::ReadOnly);
        QTextStream in(&infile);
        QString sss = in.readLine();
        QJsonDocument doc = QJsonDocument::fromJson(sss.toUtf8());
        QJsonObject json = doc.object();
        QJsonArray array = json["channels"].toArray();
        QJsonObject ch = array.at(channel-1).toObject();
    
        this->SetHigherLimit(ch.value("HigherLimit").toDouble());
        this->SetLowerLimit(ch.value("LowerLimit").toDouble());
        this->SetHigherMeasureLimit(ch.value("HigherMeasLimit").toDouble());
        this->SetLowerMeasureLimit(ch.value("LowerMeasLimit").toDouble());
        this->SetSignalType(ch.value("Type").toDouble());
        this->SetUnitsName(ch.value("Units").toString());
        this->SetMeasurePeriod(ch.value("Period").toDouble());
        this->SetState1HighMessage(ch.value("State1HighMessage").toString());
        this->SetState1LowMessage(ch.value("State1LowMessage").toString());
        this->SetState2HighMessage(ch.value("State2HighMessage").toString());
        this->SetState2LowMessage(ch.value("State2LowMessage").toString());
        this->SetState1Value(ch.value("State1Value").toDouble());
        this->SetState2Value(ch.value("State2Value").toDouble());
        this->SetChannelName(ch.value("Name").toString());
        this->SetMathematical(ch.value("MathWork").toBool());
        this->SetMathEquation(ch.value("MathString").toString());
    
        infile.close();
    }
    

    And i have a thread that reads data from that signal channels.

    void ModBus::ReadAllChannelsThread ()
    {
        UartDriver UD;
        double currentdata;
        this->thread()->setPriority(QThread::LowPriority);
    
        while (1)
        {
            while (
                   (UartDriver::needtoupdatechannel[0] == 0)&&
                   (UartDriver::needtoupdatechannel[1] == 0)&&
                   (UartDriver::needtoupdatechannel[2] == 0)&&
                   (UartDriver::needtoupdatechannel[3] == 0))
            {
                this->thread()->msleep(20);
            }
    
            if (UartDriver::needtoupdatechannel[0] == 1)
            {
                UartDriver::needtoupdatechannel[0] = 0;
                //  currentdata = ClickRelay(ModBus::Board4AIAddress);
    
                currentdata = ReadDataChannel(ModBus::ElmetroChannelAB1Address);
    
                if (currentdata!=0)
                {
                    UD.writechannelvalue(1,currentdata);
                }
                this->thread()->msleep(25);
            }
    
            currentdata=0;
    
            if (UartDriver::needtoupdatechannel[1] == 1)
            {
                UartDriver::needtoupdatechannel[1] = 0;
                currentdata = ReadDataChannel(ModBus::ElmetroChannelAB2Address);
                if (currentdata!=0)
                {
                    UD.writechannelvalue(2,currentdata);
                }
                this->thread()->msleep(25);
            }
    
            currentdata=0;
    
            if (UartDriver::needtoupdatechannel[2] == 1)
            {
                UartDriver::needtoupdatechannel[2] = 0;
                currentdata = ReadDataChannel(ModBus::ElmetroChannelAB3Address);
                if (currentdata!=0)
                {
                    UD.writechannelvalue(3,currentdata);
                }
                this->thread()->msleep(25);
            }
            currentdata=0;
    
            if (UartDriver::needtoupdatechannel[3] == 1)
            {
                UartDriver::needtoupdatechannel[3] = 0;
                currentdata = ReadDataChannel(ModBus::ElmetroChannelAB4Address);
                if (currentdata!=0)
                {
                    UD.writechannelvalue(4,currentdata);
                }
                this->thread()->msleep(25);
            }
            currentdata=0;
        }
    }
    

    Now i want to read data in that Thread that depends of signal type.

    For example if channel's signal type is Volts i want to:

     currentdata = ReadVoltage(ModBus::ElmetroChannelAB1Address);
    

    ... if it's Termocouple i want to:

     currentdata = ReadThermocouple(ModBus::ElmetroChannelAB1Address);
    

    the question is how this thread should to know signal type of each of 4 objects that are defined in MainWindow.

    And please any review of my hard code is pleased. Thanks

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Andrey Shmelew
      wrote on last edited by
      #2

      tried to start thread with 4 objects, but i bet it's not a good idea

          thread2= new QThread();
          ModBus *MB;
          MB = new ModBus();
          MB->moveToThread(thread2);
          //connect(thread2, SIGNAL(started()), MB, SLOT(ReadAllChannelsThread()) );
          thread2->start();
          connect( this, SIGNAL(ThreadSignal( ChannelOptions*, ChannelOptions*,ChannelOptions*, ChannelOptions* )), MB, SLOT(ThreadReact(ChannelOptions*,ChannelOptions*,ChannelOptions*,ChannelOptions*)) ); //
          connect(MB, SIGNAL(finished()), MB, SLOT(deleteLater()));
          ThreadSignal(&channel1object,&channel2object,&channel3object,&channel4object);
      
      1 Reply Last reply
      0
      • A Offline
        A Offline
        ambershark
        wrote on last edited by
        #3

        So this is dangerous. You are passing memory around between threads without any sort of thread synchronization.

        Your objects are not mutexed. If you happen to write in both threads at once you will crash. If you read while writing in a thread you will crash.

        Do the ChannelOption objects really need to be created in the main thread? It's fine if they do but if you pass them to other threads you will need to protect them with QMutex or some other synchronization object.

        As for passing 4 objects, there's nothing wrong with that. If you wanted to combine them into one you could just do a QList<ChannelObject *> or something. Then you are just passing one. You could also make a class or struct. I would do the class route to handle mutexing for you as well.

        My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

        A 1 Reply Last reply
        1
        • A ambershark

          So this is dangerous. You are passing memory around between threads without any sort of thread synchronization.

          Your objects are not mutexed. If you happen to write in both threads at once you will crash. If you read while writing in a thread you will crash.

          Do the ChannelOption objects really need to be created in the main thread? It's fine if they do but if you pass them to other threads you will need to protect them with QMutex or some other synchronization object.

          As for passing 4 objects, there's nothing wrong with that. If you wanted to combine them into one you could just do a QList<ChannelObject *> or something. Then you are just passing one. You could also make a class or struct. I would do the class route to handle mutexing for you as well.

          A Offline
          A Offline
          Andrey Shmelew
          wrote on last edited by
          #4

          @ambershark

          Cool, thank you, very useful!

          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