Scheduler Design? Multiple Events on the same timeline starting at different times - c++

I have multiple objects (Object1, Object2 and Object3) which MAY want to utilize a callback. If it is decided that an object wants to be registed
for a periodic callback, they all will use a 30 second reset rate. The object will choose when it registers for a callback (that it would want
at that fixed interval of 30 seconds going forward).
If I wanted to give each object its own internal Timer (such as a timer on a seperate thread) this would be a simple
problem. However each timer would need to be on a seperate thread, which would grow too much as my object count grows.
So for example:
at T=10 seconds into runtime, Object 1 registers for a callback. Since the callback occurs every 30 seconds, its next fire event will
be at T=40, then T=70, T=100 etc.
say 5 seconds later (T=15), Object 2 registers for a callback. Meaning its next call is at T=45, T=75, T=105 etc.
Lastly 1 second after Object 2, Object 3 registers for a callback. Its callback should be invoked at T=46 etc.
A dirty solution I would have for this to for everything to calculate its delta from the first registered Object.
So Object 0 is 0, Object 1 is 10 and Object 3 is 11. Then in a constantly running loop, once the 30 seconds have elapsed, I know
that Object 0's callback can process, and within 10 seconds from that point I can then call object 1's callback etc.
I don't like that in a way that stay busy waits as a while loop must constantly be running. I guess SystemSleep calls may not be as different using semaphores.
Another thought I had was finding the lowest common multiple between the fire events. For example if I kew it was possible every 3 seconds I may have to fire an event, i would keep track of that.
I think essentially what I am trying to make is some sort of simple scheduler? I'm sure I am hardly the first person to do this.
I am trying to come up with a performant solution. a While Loop or a ton of timers on their own threads would make this easy, but that is not a good solution.
Any ideas? Is there a name for this design?

Normally you would use a priority queue, a heap or similar to manage your timed callbacks using a single timer. You check what callback needs to be called next and that is the time you set for the timer to wake you up.
But if all callbacks use a constant 30s repeat then you can just use a queue. New callbacks are added to the end as a pair of callback and (absolute) timestamp and the next callback to call will always be at the front. Every time you call a callback you add it back to the queue with a timestamp 30s increased.

Related

Debounce Events in Cloud

I am looking for a good cloud solution to handle below scenario, where I need to wait for future events within a specific time interval to know whether to process current event. Its kindoff like Debounce (“group” multiple sequential calls within a time period in a single one) but little more complex as the timer needs to be reset when next event is received.
Eg:
I get a request of Event A at X time for a particular User(U1).
a. If I get a similar Event A from same User within 5mins of X time, I need to reset the timer and keep watching again.
b. If 5 mins have passed by, I need to process Event A.

How to efficiently handle incoming delayed events on a single timeline?

I want to implement the algorithm that awaits for some events and handles them after some delay. Each event has it's own predefined delay. The handler may be executed in a separate thread. The issues with the CPU throttling, the host overload, etc. may be ignored - it's not intended to be a precise real-time system.
Example.
At moment N arrives an event with delay 1 second. We want to handle it at moment N + 1 sec.
At moment N + 0.5 sec arrives another event with delay 0.3 seconds. We want to handle it at moment N + 0.8 sec.
Approaches.
The only straightforward approach that comes to my mind is to use a loop with minimal possible delay inbetween iterations, like every 10 ms, and check if any event on our timeline should be handled now. But it's not a good idea since the delays may vary on scale from 10 ms to 10 minutes.
Another approach is to have a single thread that sleeps between events. But I can't figure out how to forcefully "wake" it when there is a new event that should be handled between now and the next scheduled wake up.
Also it's possible to use a thread per event and just sleep, but there may be thousands of simultanious events which effectively may lead to running out of threads.
The solution can be language-agnostic, but I prefer the C++ STD library solution.
Another approach is to have a single thread that sleeps between events. But I can't figure out how to forcefully "wake" it when there is a new event that should be handled between now and the next scheduled wake up.
I suppose solution to these problems are, at least on *nix systems, poll or epoll with some help of timer. It allows you to make the thread sleep until some given event. The given event may be something appearing on stdin or timer timeout. Since the question was about a general algorithm/idea of algorithm and the code would take a lot of space I am giving just pseudocode:
epoll = create_epoll();
timers = vector<timer>{};
while(true) {
event = epoll.wait_for_event(timers);
if (event.is_timer_timeout()) {
t = timers.find_timed_out();
t.handle_event();
timers.erase(t);
} else if (event.is_incoming_stdin_data()) {
data = stdin.read();
timers.push_back(create_timer(data));
}
}
Two threads that share a priority queue.
Arrivals thread: Wait for arrival. When event arrives calculate time for handler to run. Add handler to queue with priority of handler time ( the top of the queue will be the next event that is to be handled
Handler thread: Is now equal to time of handler at top of queue then run handler. Sleep for clock resolution.
Note: check if your queue is thread safe. If not, then you will have to use a mutex.
This looks simple, but there a lot of gotchas waiting for the inexperienced. So, I would not recommend coding this from scratch. It is better to use a library. The classic is boost::asio. However, this is beginning to show its age and has way more bells and whistles than are needed. So, personally, I use something more lightweight and coded in C++17 - a non blocking event waiter class I coded that you can get from https://github.com/JamesBremner/await. Notice the sample application using this class which does most of what you require https://github.com/JamesBremner/await/wiki/Event-Server

Proper use of timers in Qt

I wanted to program an interval-timer which you can use for training. So there have to be a stack widget were the user can input the times for the training- and the rest-rounds and the repetitions followed by a press on a start button which changes the page and starts the first round-countdown shown in a display.
So if the user enter 20 seconds for training, 10 seconds for rest and 3 repetitions the numbers
20 to 0, 10 to 0, 20 to 0, 10 to 0 and 20 to 0
should be displayed one after another.
The problem I ran in:
I tried QTimer and a QThread with a 1 sec-sleep-function and a signal-slot to the gui, but in both options the gui froze.
The use of a QTimer will not block the main window. This is the purpose of timers.
Moreover, you don't need to use threads at all, you only have to start a timer with the desired interval (for example, a tick every 10ms) and connect the timeout() signal to a slot that will process your application behaviour.
In this slot, you just have to handle the countdown and the state change (working time to break time if the number of repetitions is not reached, break time to working time and the finished state).
I have created such an application and it worked well. Maybe I will later make it available on github. If I do it, I would made an edit to my answer to provide the link.
I hope it helps.
I think you have designed the solution in a very complicated way. With no code it's impossible to tell you what went wrong.
If I had to develop a solution for this, it'd be in the form of interconnecting blocks, which can be delay blocks or flow control blocks (child classes of the block parent).
Each block has a next one and a trigger function. A delay block also has a time. A flow control block may have different functionalities, like pointing to a previous block only for x repetitions. You can use a global QTimer when a new delay block is triggered to trigger the next block (connect the timeout signal of the timer to the trigger function of the next block, then start the timer with the current block's time).
For instance, if you wanted to do 3 times 30s exercise, 10s rest, you'd connect two delay blocks with a repeat block.

Some questions on Multithreading and Background worker threads in windows form

I have encountered the need to use multithreading in my windows form GUI application using C++. From my research on the topic it seems background worker threads are the way to go for my purposes. According to example code I have
System::Void backgroundWorker1_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e)
{
BackgroundWorker^ worker = dynamic_cast<BackgroundWorker^>(sender);
e->Result = SomeCPUHungryFunction( safe_cast<Int32>(e->Argument), worker, e );
}
However there are a few things I need to get straight and figure out
Will a background worker thread make my multithreading life easier?
Why do I need e->Result?
What are the arguments passed into the backgroundWorker1_DoWork function for?
What is the purpose of the parameter safe_cast(e->Argument)?
What things should I do in my CPUHungryFunction()?
What if my CPUHungryFunction() has a while loop that loops indefinitely?
Do I have control over the processor time my worker thread gets?
Can more specifically control the number of times the loop loops within a set period? I don’t want to be using up cpu looping 1000s of times a second when I only need to loop 30 times a second.
*Is it necessary to control the rate at which the GUI is updated?
Will a background worker thread make my multithreading life easier?
Yes, very much so. It helps you deal with the fact that you cannot update the UI from a worker thread. Particularly the ProgressChanged event lets you show progress and the RunWorkerCompleted event lets you use the results of the worker thread to update the UI without you having to deal with the cross-threading problem.
Why do I need e->Result?
To pass back the result of the work you did to the UI thread. You get the value back in your RunWorkerCompleted event handler, e->Result property. From which you then update the UI with the result.
What are the arguments passed into the function for?
To tell the worker thread what to do, it is optional. Otherwise identical to passing arguments to any method, just more awkward since you don't get to chose the arguments. You typically pass some kind of value from your UI for example, use a little helper class if you need to pass more than one. Always favor this over trying to obtain UI values in the worker, that's very troublesome.
What things should I do in my CPUHungryFunction()?
Burn CPU cycles of course. Or in general do something that takes a long time, like a dbase query. Which doesn't burn CPU cycles but takes too long to allow the UI thread to go dead while waiting for the result. Roughly, whenever you need to do something that takes more than a second then you should execute it on a worker thread instead of the UI thread.
What if my CPUHungryFunction() has a while loop that loops indefinitely?
Then your worker never completes and never produces a result. This may be useful but it isn't common. You would not typically use a BGW for this, just a regular Thread that has its IsBackground property set to true.
Do I have control over the processor time my worker thread gets?
You have some by artificially slowing it down by calling Thread.Sleep(). This is not a common thing to do, the point of starting a worker thread is to do work. A thread that sleeps is using an expensive resource in a non-productive way.
Can more specifically control the number of times the loop loops within a set period? I don’t want to be using up cpu looping 1000s of times a second when I only need to loop 30 times a second.
Same as above, you'd have to sleep. Do so by executing the loop 30 times and then sleep for a second.
Is it necessary to control the rate at which the GUI is updated?
Yes, that's very important. ReportProgress() can be a fire-hose, generating many thousands of UI updates per second. You can easily get into a problem with this when the UI thread just can't keep up with that rate. You'll notice, the UI thread stops taking care of its regular duties, like painting the UI and responding to input. Because it keeps having to deal with another invoke request to run the ProgressChanged event handler. The side-effect is that the UI looks frozen, you've got the exact problem back you were trying to solve with a worker. It isn't actually frozen, it just looks that way, it is still running the event handler. But your user won't see the difference.
The one thing to keep in mind is that ReportProgress() only needs to keep human eyes happy. Which cannot see updates that happen more frequently than 20 times per second. Beyond that, it just turns into an unreadable blur. So don't waste time on UI updates that just are not useful anyway. You'll automatically also avoid the fire-hose problem. Tuning the update rate is something you have to program, it isn't built into BGW.
I will try to answer you question by question
Yes
DoWork is a void method (and need to be so). Also DoWork executes
in a different thread from the calling one, so you need to have a
way to return something to the calling thread. The e->Result
parameter will be passed to the RunWorkerCompleted event inside
the RunWorkerCompletedEventArgs
The sender argument is the backgroundworker itself that you can use
to raise events for the UI thread, the DoWorkEventArgs eventually
contains parameters passed from the calling thread (the one who has
called RunWorkerAsync(Object))
Whatever you have need to do. Paying attention to the userinterface
elements that are not accessible from the DoWork thread. Usually, one
calculate the percentage of work done and update the UI (a progress
bar or something alike) and call ReportProgress to communicate with
the UI thread. (Need to have WorkerReportProgress property set to
True)
Nothing runs indefinitely. You can always unplug the cord.
Seriously, it is just another thread, the OS takes care of it and
destroys everything when your app ends.
Not sure what do you mean with this, but it is probably related
to the next question
You can use the Thread.Sleep or Thread.Join methods to release the
CPU time after one loop. The exact timing to sleep should be fine
tuned depending on what you are doing, the workload of the current
system and the raw speed of your processor
Please refer to MSDN docs on BackgroundWorker and Thread classes

SetTimer() pitfalls

I have a windowless timer (no WM_TIMER) which fires a callback function only once when a given time period is elapsed. It is implemented as a SetTimer()/KillTimer(). Time periods are small enough: 100-300 milliseconds.
Is that cheap enough (I mean performance) to call SetTimer()/KillTimer() pair for every such short time interval?
What if I have 100 such timers which periodically call SetTimer()/KillTimer()? How much Window timer objects may exist simultaneously in the system?
That is the question:
Use a bunch of such timer objects and rely on good Windows implementation of timers, or create one Windows timer object that ticks every, say, 30 milliseconds, and subscribe all custom 100-300 milliseconds one-time timers to it.
Thanks
The problem with timer messages as you are trying to use them is that they are low priority messages. Actually they are fake messages. Timers are associated with an underlying kernel timer object - when the message loop detects the kernel timer is signalled it simply marks the current threads message queue with a flag indicating that the next call to GetMessage - WHEN THERE ARE NO OTHER MESSAGES TO PROCESS - should synthesise a WM_TIMER message just in time and return it.
With potentially lots of timer objects, its not at all obvious that the system will fairly signal timer messages for all the timers equally, and any system load can entirely prevent the generation of WM_TIMER messages for long periods of time.
If you are in control of the message loop, you could use maintain your own list of timer events (along with GetTickCount timestamps when they should occur) and MSGWaitForMultipleObject - instead of GetMessage to wait for messages. Use the dwTimeout parameter to provide the smallest interval - from now - until the next timer should be signalled. So it will return from waiting for messages each time you have a timer to process.
And/Or you could use waitable timers - either on a GUI thread with MSGWaitForMultipleObjects, or just on a worker thread, to access the lower level timing functionality directly.
The biggest SetTimer() pitfall is that actually it is USER object (despite the fact it's not listed in MSDN USER objects list) hence it falls under Windows USER objects limitation - by default max 10000 objects per process, max 65535 objects per session (all running processes).
This can be easily proven by simple test - just call SetTimer() (parameters don't care, both windowed and windowless act the same way) and see USER objects count increased in Task Manager.
Also see ReactOS ntuser.h source and this article. Both of them state that TYPE_TIMER is one of USER handle types.
So beware - creating a bunch of timers could exhaust your system resources and make your process crash or even entire system unresponsive.
Here are the details that I feel you're actually after while asking this question:
SetTimer() will first scan the non-kernel timer list (doubly linked list) to see if the timer ID already exists. If the timer exists, it will simply be reset. If not, an HMAllocObject call occurs and creates space for the structure. The timer struct will then be populated and linked to the head of the list.
This will be the total overhead for creating each your 100 timers. That's exactly what the routine does, save for checking against the min and max dwElapsed parameters.
As far as timer expiration goes, the timer list is scanned at (approximately) the duration of the smallest timer duration seen during the last timer list scan. (Actually, what really happens is -- a kernel timer is set to the duration of the smallest user timer found, and this kernel timer wakes up the thread that does the checking for user timer expirations and wakes the respective threads via setting a flag in their message queue status.)
For each timer in the list, the current delta between the last time (in ms) the timer list was scanned and the current time (in ms) is decremented from each timer in the list. When one is due (<= 0 remaining), it's flagged as "ready" in its own struct and and a pointer to the thread info is read from the timer struct and used to wake the respective thread by setting the thread's QS_TIMER flag. It then increments your message queue's CurrentTimersReady counter. That's all timer expiration does. No actual messages are posted.
When your main message pump calls GetMessage(), when no other messages are available, GetMessage() checks for QS_TIMER in your thread's wake bits, and if set -- generates a WM_TIMER message by scanning the full user timer list for the smallest timer in the list flagged READY and that is associated with your thread id. It then decrements your thread CurrentTimersReady count, and if 0, clears the timer wake bit. Your next call to GetMessage() will cause the same thing to occur until all timers are exhausted.
One shot timers stay instantiated. When they expire, they're flagged as WAITING. The next call to SetTimer() with the same timer ID will simply update and re-activate the original. Both one shot and periodic timers reset themselves and only die with KillTimer or when your thread or window are destroyed.
The Windows implementation is very basic, and I think it'd be trivial for you to write a more performant implementation.