I need to capture the event of a terminal resize, to do this I am capturing (although other methods are welcome) SIGWINCH with the following:
std::signal(SIGWINCH, &handle_sigwinch);
I was then hoping to have handle_sinwinch do something like:
display_type *dt; //inited elsewhere
void handle_sinwinch(int sig) {
dt->async_redraw();
}
Where async_redraw post the work to do onto an internal boost::asio::io_service and then returns. Thus there should be no race conditions; however, the doc for std::signal seems to imply that I can safely ONLY manipulate volatile std::sig_atomic_ts.
IE I can set a flag, then pick it up from the main thread as a part of an event loop.
The problem is that this is asynchronous so there is no while(true) loop or anything like that. The only way to loop over such a flag would be to create a deadline timer and check it periodically. Which seems like a real hack.
So my question is, is my understanding of signals correct? And any insight how to do this would be appreciated.
If you use boost::asio you can handle signals with async_wait() method of boost::asio::signal_set. Handler set with async_wait() can do what you want, it is not called in signal handler context.
Related
I have an ordinary GUI Thread (Main Window) and want to attach a Worker thread to it. The Worker thread will be instantiated, moved to its own thread and then fired away to run on its own independently, running a messaging routine (non-blocking).
This is where the worker is created:
void MainWindow::on_connectButton_clicked()
{
Worker* workwork;
workwork= new Worker();
connect(workwork,SIGNAL(invokeTestResultsUpdate(int,quint8)),
this,SLOT(updateTestResults(int,quint8)),Qt::QueuedConnection);
connect(this,SIGNAL(emitInit()),workwork,SLOT(init()));
workwork->startBC();
}
This is where the Worker starts:
void Worker::startBC()
{
t1553 = new QThread();
this->moveToThread(t1553);
connect(t1553,SIGNAL(started()),this,SLOT(run1553Process()));
t1553->start();
}
I have two problems here, regarding the event queue of the new thread:
The first and minor problem is that, while I can receive the signals from the Worker thread (namely: invokeTestResultsUpdate), I cannot invoke the init method by emitting the emitInit signal from MainWindow. It just doesn't fire unless I call it directly or connect it via Qt::DirectConnection . Why is this happening? Because I have to start the Worker thread's own messaging loop explicitly? Or some other thing I'm not aware of? (I really fail to wrap my head around the concept of Thread/Event Loop/Signal Slot mechanism and the relation between each other even though I try. I welcome any fresh perspective here too.)
The second and more obscure problem is: run1553process method does some heavy work. By heavy work, I mean a very high rate of data. There is a loop running, and I try to receive the data flowing from a device (real-time) as soon as it lands in the buffer, using mostly extern API functions. Then throw the mentioned invokeTestResultsUpdate signal towards the GUI each time it receives a message, updating the message number box. It's nothing more than that.
The thing I'm experiencing is weird; normally the messaging routine is mostly unhindered but when I resize the main window, move it, or hide/show the window, the Worker thread skips many messages. And the resizing action is really slow (not responds very fast). It's really giving me a cancer.
(Note: I have tried subclassing QThread before, it did not mitigate the problem.)
I've been reading all the "Thread Affinity" topics and tried to apply them but it still behaves like it is somehow interrupted by the GUI thread's events at some point. I can understand MainWindow's troubles since there are many messages at the queue to be executed (both the invoked slots and the GUI events). But I cannot see as to why a background thread is affected by the GUI events. I really need to have an extremely robust and unhindered message routine running seperately behind, firing and forgetting the signals and not giving a damn about anything.
I'm really desperate for any help right now, so any bit of information is useful for me. Please do not hesitate to throw ideas.
TL;DR: call QCoreApplication::processEvents(); periodiacally inside run1553process.
Full explanation:
Signals from the main thread are put in a queue and executed once the event loop in the second thread takes control. In your implementation you call run1553Process as soon as the thread starts. the control will not go back to the event loop until the end of that function or QCoreApplication::processEvents is manually invoked so signals will just sit there waiting for the event loop to pick them up.
P.S.
you are leaking both the worker and the thread in the code above
P.P.S.
Data streams from devices normally provide an asynchronous API instead of you having to poll them indefinetly
I finally found the problem.
The crucial mistake was connecting the QThread's built in start() signal to run1553Process() slot. I had thought of this as replacing run() with this method, and expected everything to be fine. But this caused the actual run() method to get blocked, therefore preventing the event loop to start.
As stated in qthread.cpp:
void QThread::run()
{
(void) exec();
}
To fix this, I didn't touch the original start() signal, instead connected another signal to my run1553Process() independently. First started the thread ordinarily, allowed the event loop to start, then fired my other signals. That did it, now my Worker can receive all the messages.
I think now I understand the relation between threads and events better.
By the way, this solution did not take care of the message skipping problem entirely, but I feel that's caused by another factor (like my message reading implementation).
Thanks everyone for the ideas. I hope the solution helps some other poor guy like me.
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.
In a simple MFC application, I need to have a worker thread that constantly poll an ioctl for an event. At first, I attempted to achieve this using non-overlapped ioctl inside a while loop. The way I figured it is that if the ioctl does not complete io request immediately the thread will transfer control or context switch to another thread(the main thread or the MFC message control loop) but instead it locks up the application.
In a second attempt I use an overlapped and the problem is gone. But it seems to me that the two methods are identical in behavior since I use WaitForSingleObject which waits for the event (io request to finish) to trigger.
The basic layout is the following. Note that following code is incomplete and there to show only the construct
Synchronous:
WaitForIo {
do {
DeviceIoControl(hDevice,ioctl_code, ..., NULL);
do something after io request completed
} while(1);
return;
}
Asynchronous:
WaitForIo {
do {
Overlapped ov;
//CreateEvent
DeviceIoControl(hDevice,ioctl_code, ..., &ov);
WaitForSingleObject
do something after io request completed
} while(1);
}
why is the two methods behave differently? Is there something wrong in my logic?
If it locks the thread, it means you need to give back the processor by making it sleep or something like that. WaitForSingleObject does exactly that by default when you call it. I'm not sure about it, but I think that putting null in the DeviceIoControl function made it wait while keeping control over the thread - and so locks the thread.
I have a simple client-server program written in Qt, where processes communicate using MPI. The basic design I'm trying to implement is the following:
The first process (the "server") launches a GUI (derived from QMainWindow), which listens for messages from the clients (using repeat fire QTimers and asynchronous MPI receive calls), updates the GUI depending on what messages it receives, and sends a reply to every message.
Every other process (the "clients") runs in an infinite loop, and all they are intended to do is send a message to the server process, receive the reply, go to sleep for a while, then wake up and repeat. Every process instantiates a single object derived from QThread, and calls its start() method. The run() method of these classes all look like this:
from foo.cpp:
void Foo::run()
{
while (true)
{
// Send message to the first process
// Wait for a reply
// Do uninteresting stuff with the reply
sleep(3); // also tried QThread::sleep(3)
}
}
In the client's code, there is no call to exec() anywhere, so no event loop should start.
The problem is that the clients never wake up from sleeping (if I surround the sleep() call with two writes to a log file, only the first one is executed, control never reaches the second). Is this because I didn't start the event loop? And if so, what is the simplest way to achieve the desired functionality?
Some classes in client code may need an event loop to be started. Why to use QThreads for clients if you don't have an event loop for the clients and you already using MPI?
A one liner answer to the question is - sleep and event loop are not related.
Sleep makes the calling thread sleep irrespective of whether it's being called from thread's overridden run() function or any other function for that matter. It makes no difference and there is no escape.
In fact, if exec() is called somewhere in run() (which the QThread's default implementation is) the control will not return to the caller.
The reason for the second log statement not getting written cannot be directly related with sleep() if the logger object is local or available to the run() function all the time. The control has to return to thread after designated amount of sleep is done. But meanwhile, the thread could lose control to transient objects like incoming connection.
Perhaps when this question was asked QThread::sleep() was a private function. Now with Qt 5, sleep or msleep or even usleep are public static functions.
I'm importing a portion of existing code into my Qt app and noticed a sleep function in there. I see that this type of function has no place in event programming. What should I do instead?
UPDATE: After thought and feedback I would say the answer is: call sleep outside the GUI main thread only and if you need to wait in the GUI thread use processEvents() or an event loop, this will prevent the GUI from freezing.
It isn't pretty but I found this in the Qt mailing list archives:
The sleep method of QThread is protected, but you can expose it like so:
class SleeperThread : public QThread
{
public:
static void msleep(unsigned long msecs)
{
QThread::msleep(msecs);
}
};
Then just call:
SleeperThread::msleep(1000);
from any thread.
However, a more elegant solution would be to refactor your code to use a QTimer - this might require you saving the state so you know what to do when the timer goes off.
I don't recommend sleep in a event based system but if you want to ...
You can use a waitcondition, that way you can always interrupt the sleep if neccesary.
//...
QMutex dummy;
dummy.lock();
QWaitCondition waitCondition;
waitCondition.wait(&dummy, waitTime);
//...
The reason why sleep is a bad idea in event based programming is because event based programming is effectively a form on non-preemptive multitasking. By calling sleep, you prevent any other event becoming active and therefore blocking the processing of the thread.
In a request response scenario for udp packets, send the request and immediately wait for the response. Qt has good socket APIs which will ensure that the socket does not block while waiting for the event. The event will come when it comes. In your case the QSocket::readReady signal is your friend.
If you want to schedule an event for some point of time in the future, use QTimer. This will ensure that other events are not blocked.
It is not necessary to break down the events at all. All I needed to do was to call QApplication::processEvents() where sleep() was and this prevents the GUI from freezing.
I don't know how the QTs handle the events internally, but on most systems at the lowest level the application life goes like this: the main thread code is basically a loop (the message loop), in which, at each iteration, the application calls a function that gives to it a new message; usually that function is blocking, i.e. if there are no messages the function does not return and the application is stopped.
Each time the function returns, the application has a new message to process, that usually has some recipient (the window to which is sent), a meaning (the message code, e.g. the mouse pointer has been moved) and some additional data (e.g. the mouse has been moved to coords 24, 12).
Now, the application has to process the message; the OS or the GUI toolkit usually do this under the hood, so with some black magic the message is dispatched to its recipient and the correct event handler is executed. When the event handler returns, the internal function that called the event handler returns, so does the one that called it and so on, until the control comes back to the main loop, that now will call again the magic message-retrieving function to get another message. This cycle goes on until the application terminates.
Now, I wrote all this to make you understand why sleep is bad in an event driven GUI application: if you notice, while a message is processed no other messages can be processed, since the main thread is busy running your event handler, that, after all, is just a function called by the message loop. So, if you make your event handler sleep, also the message loop will sleep, which means that the application in the meantime won't receive and process any other messages, including the ones that make your window repaint, so your application will look "hang" from the user perspective.
Long story short: don't use sleep unless you have to sleep for very short times (few hundreds milliseconds at most), otherwise the GUI will become unresponsive. You have several options to replace the sleeps: you can use a timer (QTimer), but it may require you to do a lot of bookkeeping between a timer event and the other. A popular alternative is to start a separate worker thread: it would just handle the UDP communication, and, being separate from the main thread, it would not cause any problem sleeping when necessary. Obviously you must take care to protect the data shared between the threads with mutexes and be careful to avoid race conditions and all the other kind of problems that occur with multithreading.