Solved 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!
-
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 :-) -
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.
-
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.
-
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.