I want to accomplish the following in pyQt:
Run task 1 and task 2, in separate threads, as parallel as possible. Only when both threads are finished, trigger running task 1 and task 2 in parallel again.
Task 1 and task 2 are serial port queries (read + write) to/from 2 different devices using the pyserial library.
Whenever I try to implement this by starting both threads, they seem to start at the same time, but I can not synchronize their finishing properly using signals/slots.
A Button click triggers the “start’ method.
def start(self): self.stop_button_pressed = False self.worker1 = Worker1() self.worker2 = Worker2() self.worker1.signals.finished.connect(self.progress) self.worker2.signals.finished.connect(self.progress) self.threadpool.start(self.worker1) self.threadpool.start(self.worker2)
worker 1 and 2 run the following functions:
`
def get_data_1(self):
self.index_1 += 1
time.sleep(0.1)
return self.index_1
def get_data_2(self):
self.index_2 += 1
time.sleep(0.1)
return self.index_2
`
Progress function, which is supposed to restart threads when active threadcount is 0:
‘
def progress(self):
if self.stop_button_pressed == True:
print(‘stop button pressed’)
return
thread_count = self.threadpool.activeThreadCount()
print(‘thread count: ‘, thread_count, ‘indices’, self.index_1, self.index_2)
if thread_count == 0:
self.start()
‘
The problem is that the threads are not reliably restarted. If both threads finish at about the same time, when they both emit finish and run the “progress” method, thread_count never reaches 0 since the variable is not updating fast enough.
Here is the printed output to the terminal:
thread count: 1 indices 1 1 thread count: 0 indices 1 1 thread count: 1 indices 2 2 thread count: 0 indices 2 2 thread count: 2 indices 3 3 thread count: 0 indices 3 3 thread count: 1 indices 4 4 thread count: 1 indices 4 4
At this point, threads stopped re-executing since both finished and thread count was 1 twice on the last two iterations.
I tried many different ways to try to accomplish this behavior, but no matter how I try to implement it, it tends to end in threads stopping. The expected/intended behavior is for threads to continue running until a stop button is pressed.
I tried asking chatGPT, searching stack overflow, and google, and there seems to be no good solution. Sometimes there is mention of the GIL, but I think serial port I/O tasks can benefit from this type of synchronization.