What is the best startegy for running one-off short tasks concurrently
-
I am using PySide6
So I am aware of multiple strategies of running tasks (whether it be short or long, one-time or permanent) concurrently:
- Creating QThread and Worker and moving worker to the thread;
- Subclassing QThread (although most people do not recommend it)
- Using QThreadPool
However, I dislike how all of this seem to create so much overhead for the code and makes things complicated...
E.g. I have a small function that is blocking, which will run for let us say 0.5 seconds. I cannot afford everything to be blocked for 0.5 seconds so I need to run it concurrently, which is I know how to do, however, this seems so much overhead for what I want to do...
In regular python it may be:
threading.Thread( target=self.interface.connect, daemon=True ).start() # interface might have some threading.Event then that would indicate connection status and you would wait for event flag to be set.. self.interface.event()
In Qt I have to do all of these shenanigans, regardless of which method do I choose:
class Worker(QObject): finished = Signal() progress = Signal(int) def __init__(self, interface): self.interface = interface def run(self): self.interface.connect() # and then I would possibly wait somewhere for event flag to be set self.finished.emit() class Window(QMainWindow): def connect(self): self.thread = QThread() self.worker = Worker() self.worker.moveToThread(self.thread) self.thread.started.connect(self.worker.run) self.worker.finished.connect(self.thread.quit) self.worker.finished.connect(self.worker.deleteLater) self.thread.finished.connect(self.thread.deleteLater) self.worker.progress.connect(self.reportProgress) self.thread.start()
Then imagine, if I have some more of these methods, that I would need to run concurrently. It just becomes so cumbersome, for every time I have to create new objects, pass around interface (of peripheral for example), pass around objects, instead of regularly calling method and doing everything in one go, not to mention how cleaning up threads in pyqt is more difficult than everywhere else, because god forbid you will do something with the thread, your entire application will crash, or even worse, your peripheral will not release some resource or something and it won't work until you reset the peripheral... Other methods of concurrently running stuff aren't any better...
I was wondering what strategies are other people using for running small tasks concurrently with having as little code overhead as possible...
-
I am using PySide6
So I am aware of multiple strategies of running tasks (whether it be short or long, one-time or permanent) concurrently:
- Creating QThread and Worker and moving worker to the thread;
- Subclassing QThread (although most people do not recommend it)
- Using QThreadPool
However, I dislike how all of this seem to create so much overhead for the code and makes things complicated...
E.g. I have a small function that is blocking, which will run for let us say 0.5 seconds. I cannot afford everything to be blocked for 0.5 seconds so I need to run it concurrently, which is I know how to do, however, this seems so much overhead for what I want to do...
In regular python it may be:
threading.Thread( target=self.interface.connect, daemon=True ).start() # interface might have some threading.Event then that would indicate connection status and you would wait for event flag to be set.. self.interface.event()
In Qt I have to do all of these shenanigans, regardless of which method do I choose:
class Worker(QObject): finished = Signal() progress = Signal(int) def __init__(self, interface): self.interface = interface def run(self): self.interface.connect() # and then I would possibly wait somewhere for event flag to be set self.finished.emit() class Window(QMainWindow): def connect(self): self.thread = QThread() self.worker = Worker() self.worker.moveToThread(self.thread) self.thread.started.connect(self.worker.run) self.worker.finished.connect(self.thread.quit) self.worker.finished.connect(self.worker.deleteLater) self.thread.finished.connect(self.thread.deleteLater) self.worker.progress.connect(self.reportProgress) self.thread.start()
Then imagine, if I have some more of these methods, that I would need to run concurrently. It just becomes so cumbersome, for every time I have to create new objects, pass around interface (of peripheral for example), pass around objects, instead of regularly calling method and doing everything in one go, not to mention how cleaning up threads in pyqt is more difficult than everywhere else, because god forbid you will do something with the thread, your entire application will crash, or even worse, your peripheral will not release some resource or something and it won't work until you reset the peripheral... Other methods of concurrently running stuff aren't any better...
I was wondering what strategies are other people using for running small tasks concurrently with having as little code overhead as possible...
@JokZiz1 said in What is the best startegy for running one-off short tasks concurrently:
E.g. I have a small function that is blocking, which will run for let us say 0.5 seconds. I cannot afford everything to be blocked for 0.5 seconds so I need to run it concurrently, which is I know how to do, however, this seems so much overhead for what I want to do...
If this is the case, I would go for this
(I would not create an extra worker or subclass Thread to run a single function which takes like few seconds anyway)
-
@JokZiz1 said in What is the best startegy for running one-off short tasks concurrently:
E.g. I have a small function that is blocking, which will run for let us say 0.5 seconds. I cannot afford everything to be blocked for 0.5 seconds so I need to run it concurrently, which is I know how to do, however, this seems so much overhead for what I want to do...
If this is the case, I would go for this
(I would not create an extra worker or subclass Thread to run a single function which takes like few seconds anyway)
@Pl45m4
Are there any examples of how to use it, there appears to be some C++ examples for older versions of QT, and none of that is relevant, as methods provided there do not exist and I cannot find these methods, meanwhile the documentation you have provided is essentially useless, there is nothing there and no explanation on how to use it, it seems only to be available in C++, or am I wrong? Because inside the Python module there is nothing that is mentioned here https://doc.qt.io/qt-6/qtconcurrent-index.html -
@Pl45m4
Are there any examples of how to use it, there appears to be some C++ examples for older versions of QT, and none of that is relevant, as methods provided there do not exist and I cannot find these methods, meanwhile the documentation you have provided is essentially useless, there is nothing there and no explanation on how to use it, it seems only to be available in C++, or am I wrong? Because inside the Python module there is nothing that is mentioned here https://doc.qt.io/qt-6/qtconcurrent-index.htmlBut https://doc.qt.io/qtforpython-6/overviews/qtconcurrentrun.html shows you on how to use it. I would say even me could use it with this even though I only do python scripting.
-
But https://doc.qt.io/qtforpython-6/overviews/qtconcurrentrun.html shows you on how to use it. I would say even me could use it with this even though I only do python scripting.
None of the things that are shown in the page provided exist in my PySide6 package. I am using PySide 6.6.1. No things like QtConcurrent.run, QtConcurrent.map, QtConcurrent.future, as a matter of fact, my PySide6.QtConcurrent file is almost empty, with no reference to what is mentioned in documentation that you have provided
-
So I found a Stack Overflow post that claims that QtConcurrent is a namespace, not a class and it is not implementable in Python, since it is template-based and templates are a C++ feature, therefore, the aforementioned Python documentation on how to use it is just auto-generated garbage and none of it actually exists in Python. Am I misunderstanding it?
I suppose I am stuck to using QThread for every minor thing....
https://stackoverflow.com/questions/32378719/qtconcurrent-in-pyside-pyqt