What is a reasonable reaction time to posix signals intending to quit the application?
In other words, how long may my sigint, sigterm or sigtstp handling take before the system kills the application during shutdown, runlevel switching or other automated situations?
I'm writing a non graphical qt application that has to respond to signals in order to clean up before terminating. this is my current implementation:
#include "posixsignals.h"
#include <signal.h>
QAtomicInt posixSignals::sig(0);
posixSignals::posixSignals()
{
//connect to posix signals
signal(SIGINT, posixSignals::interrupt);
signal(SIGTSTP, posixSignals::interrupt);
signal(SIGTERM, posixSignals::interrupt);
//connect and start QTimer t
connect(&t, SIGNAL(timeout()), this, SLOT(check()));
t.start(500);
}
void posixSignals::interrupt(int signal)
{
sig.testAndSetOrdered(0,signal);
}
void posixSignals::check()
{
if(sig)
emit signalCought(sig);
}
In the actual implementation i connect something to the signalCought signal in order to trigger the cleanup and exit of the application. the "problem" here is if i set the timer too low the app maxes a core, but if i set it too high, it might be killed or slow down the shutdown process noticeably.
When using init(8), scripts in /etc/init.d/ are being used to stop processes. I believe the exact mechanism as well as timing constraints may vary from distribution to distribution. In my case, the time is set to 3 seconds (you can find it in /etc/rc.d/init.d/functions file inside a killproc() function. So 3 seconds is an upper limit in general.
This parameter can also be overridden by start/stop scripts of any particular daemon/application. There are also alternatives to init.d, systemd for instance. But I am not sure how that system works so cannot tell about timeouts.
I think 3 seconds is more than enough to stop any application — it is hard to imagine what can take longer than that. In the worse case scenario — just maintain some logs to see whether your application makes it on time or not.
Hope it helps.
Instead of a polling loop, you could use sockets with a QSocketNotifier to translate the posix signals into Qt events, as described here.
Related
When I create a QTimer object in Qt 5, and start it using the start() member function, is a separate thread created that keeps track of the time and calls the timeout() function at regular intervals?
For example,
QTimer *timer = new QTimer;
timer->start(10);
connect(timer,SIGNAL(timeout()),someObject,SLOT(someFunction()));
Here, how does the program know when timeout() occurs? I think it would have to run in a separate thread, as I don't see how a sequential program could keep track of the time and continue its execution simultaneously. However, I have been unable to find any information regarding this either in the Qt documentation or anywhere else to confirm this.
I have read the official documentation, and certain questions on StackOverflow such as this and this seem very related, but I could not get my answer through them.
Could anyone explain the mechanism through which a QTimer object works?
On searching further, I found that as per this answer by Bill, it is mentioned that
Events are delivered asynchronously by the OS, which is why it appears that there's something else going on. There is, but not in your program.
Does it mean that timeout() is handled by the OS? Is there some hardware that keeps track of the time and send interrupts at appropriate intervals? But if this is the case, as many timers can run simultaneously and independently, how can each timer be separately tracked?
What is the mechanism?
Thank you.
When I create a QTimer object in Qt 5, and start it using the start()
member function, is a separate thread created that keeps track of the
time and calls the timeout() function at regular intervals?
No; creating a separate thread would be expensive and it isn't necessary, so that isn't how QTimer is implemented.
Here, how does the program know when timeout() occurs?
The QTimer::start() method can call a system time function (e.g. gettimeofday() or similar) to find out (to within a few milliseconds) what the time was that start() was called. It can then add ten milliseconds (or whatever value you specified) to that time and now it has a record indicating when the timeout() signal is supposed to be emitted next.
So having that information, what does it then do to make sure that happens?
The key fact to know is that QTimer timeout-signal-emission only works if/when your Qt program is executing inside Qt's event loop. Just about every Qt program will have something like this, usually near the bottom its main() function:
QApplication app(argc, argv);
[...]
app.exec();
Note that in a typical application, almost all of the application's time will be spent inside that exec() call; that is to say, the app.exec() call will not return until it's time for the application to exit.
So what is going on inside that exec() call while your program is running? With a big complex library like Qt it's necessarily complicated, but it's not too much of a simplification to say that it's running an event loop that looks conceptually something like this:
while(1)
{
SleepUntilThereIsSomethingToDo(); // not a real function name!
DoTheThingsThatNeedDoingNow(); // this is also a name I made up
if (timeToQuit) break;
}
So when your app is idle, the process will be put to sleep inside the SleepUntilThereIsSomethingToDo() call, but as soon as an event arrives that needs handling (e.g. the user moves the mouse, or presses a key, or data arrives on a socket, or etc), SleepUntilThereIsSomethingToDo() will return and then the code to respond to that event will be executed, resulting in the appropriate action such as the widgets updating or the timeout() signal being called.
So how does SleepUntilThereIsSomethingToDo() know when it is time to wake up and return? This will vary greatly depending on what OS you are running on, since different OS's have different APIs for handling this sort of thing, but a classic UNIX-y way to implement such a function would be with the POSIX select() call:
int select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);
Note that select() takes three different fd_set arguments, each of which can specify a number of file descriptors; by passing in the appropriate fd_set objects to those arguments you can cause select() to wake up the instant an I/O operations becomes possible on any one of a set of file descriptors you care to monitor, so that your program can then handle the I/O without delay. However, the interesting part for us is the final argument, which is a timeout-argument. In particular, you can pass in a struct timeval object here that says to select(): "If no I/O events have occurred after (this many) microseconds, then you should just give up and return anyway".
That turns out to be very useful, because by using that parameter, the SleepUntilThereIsSomethingToDo() function can do something like this (pseudocode):
void SleepUntilThereIsSomethingToDo()
{
struct timeval now = gettimeofday(); // get the current time
struct timeval nextQTimerTime = [...]; // time at which we want to emit a timeout() signal, as was calculated earlier inside QTimer::start()
struct timeval maxSleepTimeInterval = (nextQTimerTime-now);
select([...], &maxSleepTimeInterval); // sleep until the appointed time (or until I/O arrives, whichever comes first)
}
void DoTheThingsThatNeedDoingNow()
{
// Is it time to emit the timeout() signal yet?
struct timeval now = gettimeofday();
if (now >= nextQTimerTime) emit timeout();
[... do any other stuff that might need doing as well ...]
}
Hopefully that makes sense, and you can see how the event loop uses select()'s timeout argument to allow it to wake up and emit the timeout() signal at (approximately) the time that it had previously calculated when you called start().
Btw if the app has more than one QTimer active simultaneously, that's no problem; in that case, SleepUntilThereIsSomethingToDo() just needs to iterate over all of the active QTimers to find the one with the smallest next-timeout-time stamp, and use only that minimum timestamp for its calculation of the maximum time-interval that select() should be allowed to sleep for. Then after select() returns, DoTheThingsThatNeedDoingNow() also iterates over the active timers and emits a timeout signal only for those whose next-timeout-time stamp is not greater than the current time. The event-loop repeats (as quickly or as slowly as necessary) to give a semblance of multithreaded behavior without actually requiring multiple threads.
Looking at the documentation about timers and at the source code of QTimer and QObject we can see that the timer is running in the thread/event loop that is assigned to the object. From the doc:
For QTimer to work, you must have an event loop in your application; that is, you must call QCoreApplication::exec() somewhere. Timer events will be delivered only while the event loop is running.
In multithreaded applications, you can use QTimer in any thread that has an event loop. To start an event loop from a non-GUI thread, use QThread::exec(). Qt uses the timer's thread affinity to determine which thread will emit the timeout() signal. Because of this, you must start and stop the timer in its thread; it is not possible to start a timer from another thread.
Internally, QTimer simply uses the QObject::startTimer method to fire after a certain amount of time. This one itself somehow tells the thread it's running on to fire after the amount of time.
So your program is fine running continously and keeping track of the timers as long as you don't block your event queue. If you are worried of your timer being not 100% accurate try to move long-running callbacks out of the event queue in their own thread, or use a different event queue for the timers.
QTimer object registers itself into EventDispatcher (QAbstractEventDispatcher) which than takes care to send events of type QTimerEvent every time there is timeout for a particular registered QTimer. For example, on GNU/Linux there is a private implementation of QAbstractEventDispatcher called QEventDispatcherUNIXPrivate that makes calculations taking in consideration the platform api for the time. The QTimerEvent are sent from QEventDispatcherUNIXPrivate into the queue of the event loop of the same thread where QTimer object belongs, i.e. was created.
QEventDispatcherUNIXPrivate doesn't fire a QTimerEvent because of some OS system event or clock, but because it periodically checkes the timeout when processEvents is called by the thread event loop where QTimer lives too. Se here: https://code.woboq.org/qt5/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp.html#_ZN27QEventDispatcherUNIXPrivateC1Ev
I have a Qt application that runs on Linux.
The user can switch the system to mem sleep using this application.
Switching to mem sleep is trivial, but catching the wake up event in user space isn't.
My current solution is to use a infinite loop to trap the mem sleep, so that when the system wakes up, my application always continues from a predictable point.
Here is my code:
void MainWindow::memSleep()
{
int fd;
fd = ::open("/sys/power/state", O_RDWR);// see update 1)
QTime start=QTime::currentTime();
write(fd,"mem",3); // command that triggers mem sleep
while(1){
usleep(5000); // delay 5ms
const QTime &end=QTime::currentTime();// check system clock
if(start.msecsTo(end)>5*2){// if time gap is more than 10ms
break; // it means this thread was frozen for more
} // than 5ms, indicating a wake up after a sleep
start=end;
}
:: close(fd); // the end of this function marks a wake up event
}
I described this method as a comment on this question, and it was pointed out that it's not a good solution, which I agree.
Question: Is there a C API that I can use to catch the wake up event?
Update:
1) what is mem sleep?
https://www.kernel.org/doc/Documentation/power/states.txt
The kernel supports up to four system sleep states generically, although three
of them depend on the platform support code to implement the low-level details
for each state.
The states are represented by strings that can be read or written to the
/sys/power/state file. Those strings may be "mem", "standby", "freeze" and
"disk", where the last one always represents hibernation (Suspend-To-Disk) and
the meaning of the remaining ones depends on the relative_sleep_states command
line argument.
2) why do I want to catch the wake up event?
Because some hardware need to be reset after a wake up. A hardware input device generates erroneous input events after system wakes up, so it has to be disabled before sleep(easy) and enable after wake up(this question).
This should/could be handled by the driver in the kernel, which I have access to, or fixed in hardware, which my team can do but does not have the time to do it.(why I, a app developer, need to fix it in user space)
3) constraints
This is embedded linux, kernel 2.6.37, arch:arm, march:omap2, distro:arago. It's not as convenient as PC distros to add packages, not does it have ACPI. And mem sleep support in kernel 2.6.37 isn't mature at all.
Linux device drivers for PCI devices can optionally handle suspend and resume which, presumably, the kernel calls, respectively, just before the system is suspended, and just after resuming from a suspend. The PCI entrypoints are in struct pci_driver.
You could write and install a trivial device driver which does nothing more than sense resume operations and provides an indication to any interested processes. The simplest might be to support a file read() which returns a single byte whenever a resume is sensed. The program only need open the device and leave a thread stuck reading a single character. Whenever the read succeeds, the system just resumed.
More to the point, if the devices your application is handling have device drivers, the drivers should be updated to react appropriately to a resume.
When the system wakes from sleep, it should generate an ACPI event, so acpid should let you detect and handle that: via an /etc/acpi/events script, by connecting to /var/run/acpid.socket, or by using acpi_listen. (acpi_listen should be an easy way to test if this will work.)
Check pm-utils which you can place a hook at /etc/pm/sleep.d
In the hook you can deliver signal to your application, e.g. by kill or any IPC.
You can also let pm-utils to do the computer suspend, which IMO is far more compatible with different configurations.
EDIT:
I'm not familiar with arago but pm-utils comes with arch and ubuntu.
Also note that, on newer system that uses systemd, pm-utils is obsoleted and you should instead put hooks on systemd.
REF: systemd power events
I am currently using a script to call pkill to terminate my C++ program.
However i noticed that the destructors were not called from my traces when using pkill.
Is there another good way that i can exit the program gracefully?
pkill seems kind of untidy and some logs in the buffer do not get recorded. I'd like to be able to flush on my fstream and to close all resources programatically (instead of relying on the O/S to clean up my mess).
The application runs 24/7 without any problem, the only time i want to stop it is during maintenance. The application does not have any user interface for me to type exit.
You do it by defining a signal handler for SIGTERM along these lines:
Somewhere in your include block:
#include <signal.h>
#include <stdio.h>
Yes, we're doing i C style!
Somewhere in the initialization part of your code:
signal (SIGTERM, handler);
and then define the signal handlers code (flush everything, etc):
void handler(int num)
{
// we might use this handler for many signals
switch (num)
{
case SIGTERM:
// clean up code.
break;
}
}
Now when you run pkill <app>, where <app> is the name of the executable, the code for handler() will run.
Without switches, the default SIGTERM signal will be sent to the application. Should you choose to use a different signal you would have to make sure you send the same signal as you "catch" in the handler().
Relevant information can be found by man 7 signal and of course, man kill.
In addition to Zrvan's answer, be aware that only a restricted set of functions can be safely called from a signal handler. The signal(7) man page, and the Posix standards, require that only Async-signal-safe functions can be called directly or indirectly inside a signal handler. Note that printf or malloc are not safe inside a signal handler. Signal handler's code is tricky to write (and you cannot debug it easily, because signal sending is non-reproducible).
As the Glibc documentation suggests, your signal handler could just set a volatile sig_atomic_t variable, which your main loop[s] would test and handle.
You could also decide, if you application is event based, that some socket or named pipe is dedicated to control it. That event loop (perhaps using select(2) or poll(2), or even pselect or ppoll) could handle the control message on the pipe or socket.
You may be interested by event looping libraries like libevent. You might also use an HTTP server library like onion or Wt. You could also be interested by SNMP or D-bus.
A trick to overcome the limitation of signal handlers is to have them write on a pipe to the same process, as e.g. Qt's doc is suggesting. Then the event loop would handle reading on that pipe.
If your application is multi-threaded, signal handling is more tricky. Some signals are delivered to an individual thread.
Unless you modify the target application, I don't see a way.
Consider the following:
int main()
{
MyClass a;
while ( true )
{
}
}
You'd have to tell the program to exit the loop. But unless you have some signal handling mechanism on your app, that seems impossible.
You'd need something like:
int main()
{
MyClass a;
while ( !killSignalReceived() )
{
}
}
The best way is to handle a signal in the program, and then send that signal using kill. In the signal handler, mark a flag that will cause the main loop to end.
I'm using the GCC compiler and C++ and I want to make a timer that triggers an interruption when the countdown is 0.
Any Ideas? Thanks in advance.
EDIT
Thanks to Adam, I know how to do it.
Now. What about multiple timers running in parallel?
Actually, these timers are for something very basic. In NCURSES, I have a list of things. When I press a key, one of the things will change colors for 5 seconds. If I press another key, another thing in the list will do the same. It's like emphasize strings depending on the user input. Is there a simpler way to do that?
An easy, portable way to implement an interrupt timer is using Boost.ASIO. Specifically, the boost::asio::deadline_timer class allows you to specify a time duration and an interrupt handler which will be executed asynchronously when the timer runs out.
See here for a quick tutorial and demonstration.
One way to do it is to use the alarm(2) system call to send a SIGALRM to your process when the timer runs out:
void sigalrm_handler(int sig)
{
// This gets called when the timer runs out. Try not to do too much here;
// the recommended practice is to set a flag (of type sig_atomic_t), and have
// code elsewhere check that flag (e.g. in the main loop of your program)
}
...
signal(SIGALRM, &sigalrm_handler); // set a signal handler
alarm(10); // set an alarm for 10 seconds from now
Take careful note of the cautions in the man page of alarm:
alarm() and setitimer() share the same timer; calls to one will interfere with use of the other.
sleep() may be implemented using SIGALRM; mixing calls to alarm() and sleep() is a bad idea.
Scheduling delays can, as ever, cause the execution of the process to be delayed by an arbitrary amount of time.
I'm implementing a checking system in C++. It runs executables with different tests. If the solution is not correct, it can take forever for it to finish with certain hard tests. That's why I want to limit the execution time to 5 seconds.
I'm using system() function to run executables:
system("./solution");
.NET has a great WaitForExit() method, what about native C++?. I'm also using Qt, so Qt-based solutions are welcome.
So is there a way to limit external process' execution time to 5 seconds?
Thanks
Use a QProcess with a QTimer so you can kill it after 5 seconds. Something like;
QProcess proc;
QTimer timer;
connect(&timer, SIGNAL(timeout()), this, SLOT(checkProcess());
proc.start("/full/path/to/solution");
timer.start(5*1000);
and implement checkProcess();
void checkProcess()
{
if (proc.state() != QProcess::NotRunning())
proc.kill();
}
Use a separate thread for doing your required work and then from another thread, issue the
pthread_cancle () call after some time (5 sec) to the worker thread. Make sure to register proper handler and thread's cancelability options.
For more details refer to: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html
Check out Boost.Thread to allow you to make the system call in a separate thread and use the timed_join method to restrict the running time.
Something like:
void run_tests()
{
system("./solution");
}
int main()
{
boost::thread test_thread(&run_tests);
if (test_thread.timed_join(boost::posix_time::seconds(5)))
{
// Thread finished within 5 seconds, all fine.
}
else
{
// Wasn't complete within 5 seconds, need to stop the thread
}
}
The hardest part is to determine how to nicely terminate the thread (note that test_thread is still running).
void WaitForExit(void*)
{
Sleep(5000);
exit(0);
}
And then use it (Windows specific):
_beginthread(WaitForExit, 0, 0);
Solution testing system on Windows should use Job objects to restrict it's access to the system and execution time (not the real time, BTW).
If you are working with Posix compliant systems (of which MacOS and Unix generally are), use fork execv and ``waitpidinstead ofsystem`.An example can be found here. The only really tricky bit now is how to get a waitpid with a timeout. Take a look here for ideas.