Qt newbie - distributed architecture advice
I need to build a distributed system:
- central dispatcher/controller sending events to agents
- multiple (many) concurrent agents waiting for events. performing a short processing loop and requesting new events from the dispatcher
The system would be generalized, adding GUI and runtime diagnostics/analytics using pseudo-reflection.
Qt sounds like a perfect tool.
- Would you use a QThread or Qt Concurrent?
- How would you integrate an event-loop (I plan to have a generic agent class, and many derived classes for actual instances) in the thread, waiting for dispatcher event, and calling process.
- I want to integrate an event filter for each agent, so that the dispatcher sends (emits a signal?) once, and all parallel agents check whether the event is applicable
- the send event is basically an ID (i.e. an "int"). Should I use a QEvent::User+ID? or just send an int?
- Is there a pattern for the dispatcher to wait for a process-done event from ALL agents, or do I need to count the separate events and compare to agent_count?
please post some pseudo-code / or link to a relevant example - preferably using latest semantics (QT-5.4/C++-11/14).
Hi, and welcome to the Qt Dev Net!
To clarify: When you say "distributed", do you mean a single program running multiple agents concurrently? Or are the agents running in different programs, or even different machines?
For now, I'll assume that you have a single program.
Have a look at the "Multithreading Technologies in Qt":http://doc.qt.io/qt-5/threads-technologies.html article (there are more options than QThread and Qt Concurrent). In summary, since your agents need event/signal handling, you need to use QThread.
Simply create your QThread object and run it. This will create a new thread with a running event loop.
A QEvent is unnecessary complication. Just send an int. (Also, QEvents are low-level. Since you are using signals and a slots, you don't need QEvent)
I would count agents.
[quote author="hrs1" date="1421285412"]please post some pseudo-code / or link to a relevant example - preferably using latest semantics (QT-5.4/C++-11/14).[/quote]Generic examples at
Thanks for the answers and tips
My distributed system is currently running on a single system with multiple threads. But regarding your question - can Qt scale its signal/slot IPC across machines?
I'm still confused regarding event processing in QThreads.
I followed the syntax in this "link":http://qt-project.org/doc/note_revisions/5/8/view , please clarify the following:
a) what is the difference between the two examples in the link: using invokeMethod vs connecting to the startWork() signal?
b) when talking about a QThreads main event processing loop - would that be Worker::doWork() ?
If so, does that mean that the thread terminates when doWork() exits?
c) do external events (signals) need to be "connect"ed to doWork() or to any other slot in the worker class?
again, thanks for your assistance.
You're most welcome :)
First, make sure you are familiar with signals and slots:
- Signals are analogous to events
- Slots are analogous to event handlers.
Also, note the similarities between the main thread and the worker thread:
- Entry points:
** main() is the top-level function in the main thread.
** QThread::run() is the top-level function in the worker thread.
- Starting event loops:
** QCoreApplication::exec() runs the event loop in the main thread.
** QThread::exec() runs the event loop in the worker thread.
- Stopping event loops:
** QCoreApplication::quit() stops the main thread's event loop, causing QCoreApplication::exec() to return.
** QThread::quit() stops the worker thread's event loop, causing QThread::exec() to return.
- Exit points:
** The main thread stops when main() returns.
** The worker thread stops when QThread::run() returns.
When you call QThread::start(), it creates a new thread and calls QThread::run() there, which in turn calls QThread::exec().
To answer your questions:
Not at the moment, but "discussions":http://comments.gmane.org/gmane.comp.lib.qt.devel/18854 are underway to implement this feature.
(a) The end result is the same, but invokeMethod() takes less work to set up. invokeMethod() only takes one line to run the slot, whereas the other method requires you to create a sender object, connect the signal to the slot, and then get the sender to emit the signal.
(b) No. In that example, doWork() is simply a slot (an event handler). Slot/event handlers, should be short functions that return quickly. The thread stops running when QThread::run() returns (see above)
(c ) It's not mandatory. You decide which signals need to connect to which slots.
Actually, I find it confusing to thing of signals and slots analogous to events. They are not.
Events are targeted at a single receiver for an event. Signals and slots maintain many-to-many relationships.
Note that there are other solutions that implement signals & slots across processes and machines already, besides Replicant. The good-old Qxt comes to mind.
[quote author="Andre" date="1421408554"]Actually, I find it confusing to thing of signals and slots analogous to events. They are not.
Events are targeted at a single receiver for an event. Signals and slots maintain many-to-many relationships.[/quote]I guess all analogies have their imperfections; what works for one person might not work for another.
I agree that signals are far more flexible than events, regarding the number of "targets"/"receivers".
[quote author="Andre" date="1421408554"]Note that there are other solutions that implement signals & slots across processes and machines already, besides Replicant. The good-old Qxt comes to mind. [/quote]Sadly, libqxt is no longer maintained for newer versions of Qt.
[EDIT: Other question split to new thread: http://qt-project.org/forums/viewthread/52178/ --JKSH]