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

Loop with inter thread communication - best design?



  • Hello,

    I would like to know what is the best way to realize an inter thread communication in the following case.

    There is a thread A where a loop is running and there is a thread B where either QSerialPort or QCanBus is used.
    The thread A does several things and also needs to write on the Com-Port oder CanBus. Then the loop must wait until a command is received on the same port or bus.

    My idea in pseudocode is the following:

    Thread A:
    int plannedRuns;
    int loopValue; 
    signal: writeToBus(); 
    
    connect(ThreadA, writeToBus, ThreadB, writeFrame, QueuedConnection)
    
    void startMeasurement(int runs)
    {
       plannedRuns = runs;
       loopValue = 0;
       workingFunction();
    }
    
    void workingFunction()
    {
        doStuff();
        loopValue++;
        if(loopValue < plannedRuns) emit writeToBus();
    }
    
    Thread B:
    writeFrame(); //Writes frames
    signal: frameAvailable() //Signal when new frames are there
    connect(ThreadB, frameAvailable, ThreadA, workingFunction, QueuedConnection)
    

    Is this a good way?

    Thank you very much!


  • Lifetime Qt Champion

    Hi,

    So you would like to follow the producer/model ?



  • @SGaist said in Loop with inter thread communication - best design?:

    So you would like to follow the producer/model ?

    I think this would be the easiest.
    Or do you have another suggestion?
    As I am not a professional programmer I am always open for suggestions :-)


  • Lifetime Qt Champion

    It will depend on what exactly is inside that package. Can you describe one use-cases.



  • I'm just speculating about your use case but, if your "Thread A" is mostly Qt UI processing, and "Thread B, ..." is a separate i/o package, I like to use a pattern I refer to as "delayed widgets" in the UI Thread A; where basically, Thread B is isolated with a "worker" class that implements QThreadPool, and the UI Thread A starts a periodic timer that "wakes up" on a reasonable interval and updates a set of status widgets from member variables real-time-updated by the worker class Thread B. An example of my UI Thread A setup code would be:

    self.timerDelayedWidgets = QTimer(self)
    self.timerDelayedWidgets.timeout.connect(self.display_DelayedWidgets)
    self.timerDelayedWidgets.start(self._DELAYED_WIDGETS_INTERVAL_MILLI)



  • Thanks for the answers.
    OK, my use case is a little bit different.

    In Thread A a sensor is measured, its data is processed and stored.
    After every measurement the sensor has to be moved.
    This is done communicating with motors over a SerialBus or CanBus.
    After the new position is reached I get a "target reached" info on the Bus and then I can start a new measurement.

    Actually after every measurement while Thread A is still processing the data, Thread B can already start moving.


  • Lifetime Qt Champion

    So in fact, you could queue your measure results for processing while moving your motor and starting the next measurement.



  • @SGaist
    Yes! This sounds really good.
    How would an implementation roughly look like?
    Basically like the pseudocode I provided, but you would put everything what can be processed later into a queue for a third thread?

    I still would like to keep threads for bus communication and basic processing separate as there is alot of traffic on the bus and I don't like the bus class to do other things than sending and receving bus messages.


  • Lifetime Qt Champion

    You can use a QQueue to store the data that needs processing.

    Emit a signal from the class where you process the messages when it's a measure result.

    You can then use a QWaitCondition to keep your measure processing thread from spinning for nothing if the queue is empty.


Log in to reply