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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.