Kind of C++ and even more Boost noobie here.
I have successfully managed to create two threads, based on this example, one Worker and one Interrupter. The latter sleeps, via this_thread::sleep_for for 50 seconds and interrupts the Worker if he is not done within that time, with proper use of while !this_thread::interruption_requested() and thread::interrupt(). So it's a very nice and easy timeout mechanism. My problem is how to stop Interrupter sleep sooner? I mean if Worker finishes before that 50 seconds, I do a this_thread::yield or this_thread::interruption_requested (both seem to work) but Interrupter is still asleep and have to wait for 50 seconds for him to wake up:(
Is there any way to do this timeout mechanism, but if Worker is done with his work before sleep is over, to notify/wake up Interrupter?
PS: Do I need some sort of synchronization when all are done?
Your interrupter thread should not sleep unconditionally for 50 seconds but wait for conditional variable for 50 seconds, if worker thread finishes earlier it will signal conditional var and interrupter would wake up. You can use either std::conditional_variable or one from boost with the same name
Related
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
If my timeslice is 3 seconds, I am guessing the alarm stops the execution of a process every three seconds. What does sleep do? Does it put the process to sleep for 3 seconds? This does not make sense to me - what if there are a lot of processes? Wouldn't it have to sleep for longer?
I am doing this with the round robin stimulation:
while (head!=NULL)
{
alarm(TIMESLICE);
sleep(TIMESLICE);
}
cout<<"no processes left"<<endl;
The code works, but I just want to understand what exactly is going on as I am new to this concept.
I am guessing the alarm stops the execution of a process every three seconds.
Sort of. It arranges for a signal to be sent to the process in three seconds. The process can then continue normally and can even ignore the signal if it wants to.
What does sleep do? Does it put the process to sleep for 3 seconds?
Correct.
This does not make sense to me - what if there are a lot of processes? Wouldn't it have to sleep for longer?
No. Even a process that never sleeps isn't guaranteed to get the CPU all the time. A process that isn't sleeping may or may not be scheduled to run on a core at any particular time. Once it's no longer sleeping, it's ready-to-run, and the scheduler will make the decision of when and for how to long to let it use what core.
I have a multithreaded application under Windows 7.
I need to correctly finish jobs in threads which have an open descriptors, connections and so on when a user presses 'X' in the corner of command line, 'Ctrl+C', shuts down OS and so on.
I've set a handler for SetConsoleHandler which sets appropriate flags for other threads to correctly finish their job. But all of them are interrupted and the y exit with code 0xc000013a. SOmetimes even my handler doesn't have time to set flag.
The same problem remains when I try to do the same operations in atexit handler.
Why are all threads stopped even during interruption handler? How can I avoid this and let all my threads finish their job?
sets appropriate flags for other threads to correctly finish their job
Usually it's not enough. You also must wait the threads to finish (thread.join(), or WaitForMultipleObjects, or something similar).
The problem in my case was that some of child-children thread used timed-waiting on system resources so each of them needed to wake from waiting to join thread. And all of them were stopping consecutively so they required too much time to stop.
I have a multi-threaded application but sometimes one thread that is suppose to wake up after 10 seconds and do some work is not getting woken up from sleep or is starving.
It only happens sporadically.
//ACE task svc method
int svc (void)
{
while(true)
{
ACE_DEBUG((MY_INFO "sleep\n"));
sleep(10);
ACE_DEBUG((MY_INFO "awake for HB\n"));
_csender.sendHeartBeat();
}
return 0;
}
The last line in the log is:
2012-06-12 11:34:20.807272|INFO|sleep
Thread either didnt awake for 15 seconds or didn't do any work after its awaken until the 15th second, so the application closed.
There are total 6 threads in the application, all started with same priority.
One of the thread is very busy, it receives a lot of market data and processes it, but does not send anything out on socket. The thread above is the only thread sending data out and both the receiver and sender threads are sharing the same socket object.
This is on red hat linux 5.3.
any ideas what could be the issue?
'Busy thread is prints 2 ACE_DEBUGs every 2 microseconds' - so probably clogging up the output queue of the debugger and preventing this thread from getting in to queue up its 'sleep\n'.
That, and/or you have prioritized down this thread and it cannot get a core, as other posters have indicated.
The sleep(10) is almost an irellevance.
Sleep does not give any guarantees about maximum time spent sleeping, i.e. you sleep for at least that amount of time, or any time longer. I don't know if it's plausible to expect a 5 second delay though, sounds far too long.
I think its in ACE_DEBUG. Did you try a printf with a flush right after the sleep?
I need to periodically do a particular task and am currently using nanosleep.
The task needs to be run every second or every 10 seconds.
Is there a better way to do this than:
while(true)
{
doTask();
sleep();
}
Walter
One of the options could be to create a thread that will do the task with specified timeout.
You can use a thread library to create a thread which handle run the doTask(). Your main thread just keeps sleeping and runs every 1 second or 10 seconds.
This can be done with a QTimer and a QRunnable.
http://doc.qt.nokia.com/latest/qtimer.html
According to the dock, the resolution is around 1 ms in most cases. For your need, this should be sufficient.