On 9/29/19 5:00 AM, Richard Weickelt wrote:
what is the expected event execution order in the following scenario?

- 2 Threads running their event loop
- Thread T1 is handling an event E1
- Thread T2 sends an event E2 to T1 (queued)
- Thread T1 (still handling E1) emits an event E3 to itself (direct) after
E2 has already been enqueued.
- E3 is a very long-running event. To prevent events from starving, T1 calls
QCoreApplication::processEvents() periodically.

Observed behaviour:
- E3 gets immediately executed
- E2 is executed after E3/E1 have completed

Is this behavior expected? I would expected E2 being executed at least on
the first invocation of QCoreApplication::processEvents(), but apparently it
sits in the event queue until T1 returns from E3 (and also E1).

In my scenario E2 is rather short and E3 expectes something from E2 in order
to complete. So I run into a deadlock here.

Would it be a solution to handle E3 in a queued connection? In case E2 is
posted after E3 has started, would E2 be executed by processEvents()?

Non-queued connections are basically local function calls. You would have to force a queued connection, but you still could not reliably get your design to work. You have a sequential problem where steps must occur in a given order but may require differing amounts of time. In effect you are trying to do this without having a full Application Control Management System.

http://h30266.www3.hpe.com/odl/vax/databases/acms45/6604/6604pro.html

You really need to split this into restartable units of work and utilize an external queing agent.

This solution hasn't properly utilized stepwise refinement. T1 _cannot_ issue E3 until there is a pending E2, but it does, so this logic isn't properly broken down. Without knowing what your application is or anything more than these BASIC (the language, not a shout) variable names, here's the 5 minute architect job.

*) Forget events. Wrong tool for this job. Having said that, you are using Qt and probably unwilling to code the necessary architecture so we will attempt to make them work. You really should use a message queing system for this if not a full blown ACMS.

*)  T1  = your T1   T2 = your T2   T3 = Control Thread (possibly main event loop)

T1 chews on whatever it chews on. When it gets to the state of issuing the previous E3 it sends a T1-TASK-COMPLETE message to the control thread.

T2 chews on whatever it chews on. When it gets to the state of issuing the previous E3 it sends a T2-TASK-COMPLETE message to control thread.

T3 receives one or more TASK-COMPLETE messages and first records them into some form of data store. Then it checks via some kind of key/id or something if it has a matching T1-TASK-COMPLETE and T2-TASK-COMPLETE. If so, it combines whatever data is in the "complete" messages and launches what was previously E3, preferably in its own thread.

Each "task" must be designed so it can run flat out without dependencies from other tasks. Your control task, depending on the required granularity could even be split into CONTROL-STORE and CONTROL-DISPATCH with the dispatch portion being triggered each time a store completes to search for matching completed tasks so the next task can be launched.

If you don't have a hardware (serial port or some other kind of polling device) or database involved in T1 I would be very worried about having to call QCoreApplication::processEvents(). If one is doing database I/O in the main event loop you could easily need to do this for a large cursor of data, but you are in a thread or at least this description is.

--
Roland Hughes, President
Logikal Solutions
(630)-205-1593

http://www.theminimumyouneedtoknow.com
http://www.infiniteexposure.net
http://www.johnsmith-book.com
http://www.logikalblog.com
http://www.interestingauthors.com/blog

_______________________________________________
Interest mailing list
[email protected]
https://lists.qt-project.org/listinfo/interest

Reply via email to