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.
Related
I am developing an UI using QTCreator using CPP. My requirement is to run a UI and need to continuously poll linux Message queue using function msgrcv() whether any data is coming to the queue. I created one thread to continuously monitor the reception queue message. While starting and running the mentioned thread, UI got stuck. Any solution for running the thread and UI in parallel?
It's impossible to tell without seeing your code. However, if the poll operation is non-blocking, then you don't actually need a thread. You can instead register a piece of code that Qt's event loop will run on each UI event loop iteration. You do that using a 0ms QTimer:
void poll_function();
// ...
QTimer poll_timer;
QObject::connect(&poll_timer, &QTimer::timeout, poll_function);
poll_timer.start();
Of course, in the above example code, poll_function() will stop getting called once poll_timer goes out of scope. In your real code, you should use a QTimer that stays alive for as long as you need it. Should probably be a data member of your QApplication subclass.
If poll_function() blocks though, then this approach will not work as it will block the UI. So you should make sure to tell msgrcv() to not block. From the man page:
If no message of the requested type is available and IPC_NOWAIT isn't specified in msgflg, the calling process is blocked
So make sure you include IPC_NOWAIT in the msgflg flags when calling msgrcv().
If polling on every UI event loop iteration is too much overhead, then you can instead set a normal timeout interval in milliseconds:
poll_timer.setInterval(500);
This will call your poll function every 500ms.
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 implemented my own Timer/Callback classes in C/C++ in Linux, wherein a process requiring a timer to fire either ONE_SHOT or PERIODICally instantiates a timer, and instantiates a callback object and associates the callback with previously created Timer object. The Callback class implements a triggered () method, and when the timer fires at the appointed timeout, the triggered () method is executed. (Nothing new in terms of functionality.) The way my Timer class works is I maintain a minheap of Timer objects and thus always know which timer to fire next. There is a timer task (TimerTask) which itself runs as a separate process (created using fork ()) and shares the memory pools from which the Timer objects and the Callback objects are created. The TimerTask has a main while (1) loop which keeps checking if the root of the Timer object minheap has a time since epoch that is LEQ the current time since epoch. If so, the timer at root has "fired."
Currently, when the timer fires, the callback is executed in the TimerTask process context. I am currently changing this behavior to run the callback processing on other tasks (send them the information that the Timer object has fired via a POSIX message queue. For example, send the message to the Timer object creating process), but my question to SO is what are the principles behind this? Executing a callback in the TimerTask context seems like a bad idea if I expect to service a large number of timers. It seems like a good idea to dispatch the callback processing over to other processes.
What are the general rules of thumb for processing the callback in one task/process over the other? My intention is to process the callback in the receiving task using a pthread like so:
void threadFunctionForTimerCallback (void* arg)
{
while (1)
{
if ((mq_receive (msg_fd, buffer, attr.mq_msgsize, NULL)) == -1)
exit (-1);
else
printf ("Message received %s\n", buffer);
}
}
Would this be a reasonable solution? But never mind the actual way of receiving the message from the TimerTask (threads or any other method, doesn't matter), any discussion and insight into the problem of assigning a task for the callback is appreciated.
There is no need to busy spin while(1) to implement a timer. One traditional and robust way of implementing timers has been using minheap as you do to organize times to expiry and then pass the time till the next timer expiry as a timeout argument to select() or epoll(). Using select() call a thread can watch for file descriptor readiness, signals and timers all at the same time.
Recent kernels support timerfd that delivers timer expiry events as file descriptor readiness for read which again can be handled using select()/epoll(). It obviates the need to maintain the minheap, however, requires a system call for each add/modify/delete a timer.
Having timer code in another process requires processes to use inter-process communication mechanisms, thereby introducing more complexity, so it can actually make the system less robust, especially when the processes communicate via shared memory and can corrupt it.
Anyway, one can use Unix domain sockets to send messages back and forth between communicating processes on the same host. Again, select()/epoll() are your best friends. Or a more high level framework can be used for message passing, such as 0MQ.
We have an API that handles event timers. This API says that it uses OS callbacks to handle timed events (using select(), apparently).
The api claims this order of execution as well:
readable events
writable events
timer events
This works by creating a point to a Timer object, but passing the create function a function callback:
Something along these lines:
Timer* theTimer = Timer::Event::create(timeInterval,&Thisclass::FunctionName);
I was wondering how this worked?
The operating system is handling the timer itself, and when it sees it fired how does it actually invoke the callback? Does the callback run in a seperate thread of execution?
When I put a pthread_self() call inside the callback function (Thisclass::FunctionName) it appears to have the same thread id as the thread where theTimer is created itself! (Very confused by this)
Also: What does that priority list above mean? What is a writable event vs a readable event vs a timer event?
Any explanation of the use of select() in this scenario is also appreciated.
Thanks!
This looks like a simple wrapper around select(2). The class keeps a list of callbacks, I guess separate for read, write, and timer expiration. Then there's something like a dispatch or wait call somewhere there that packs given file descriptors into sets, calculates minimum timeout, and invokes select with these arguments. When select returns, the wrapper probably goes over read set first, invoking read callback, then write set, then looks if any of the timers have expired and invokes those callbacks. This all might happen on the same thread, or on separate threads depending on the implementation of the wrapper.
You should read up on select and poll - they are very handy.
The general term is IO demultiplexing.
A readable event means that data is available for reading on a particular file descriptor without blocking, and a writable event means that you can write to a particular file descriptor without blocking. These are most often used with sockets and pipes. See the select() manual page for details on these.
A timer event means that a previously created timer has expired. If the library is using select() or poll(), the library itself has to keep track of timers since these functions accept a single timeout. The library must calculate the time remaining until the first timer expires, and use that for the timeout parameter. Another approach is to use timer_create(), or an older variant like setitimer() or alarm() to receive notification via a signal.
You can determine which mechanism is being used at the OS layer using a tool like strace (Linux) or truss (Solaris). These tools trace the actual system calls that are being made by the program.
At a guess, the call to create() stores the function pointer somewhere. Then, when the timer goes off, it calls the function you specified via that pointer. But as this is not a Standard C++ function, you should really read the docs or look at the source to find out for sure.
Regarding your other questions, I don't see mention of a priority list, and select() is a sort of general purpose event multiplexer.
Quite likely there's a framework that works with a typical main loop, the driving force of the main loop is the select call.
select allows you to wait for a filedescriptor to become readable or writable (or for an "exception" on the filedeescriptor) or for a timeout to occur. I'd guess the library also allow you to register callbacks for doing async IO, if it's a GUI library it'll get the low primitive GUI events via a file descriptor on unixes.
To implement timer callbacks in such a loop, you just keep a priority queue of timers and process them on select timeouts or filedescriptor events.
The priority means it processes the file i/o before the timers, which in itself takes time, could result in GUI updates eventually resulting in GUI event handlers being run, or other tasks spending time servicing I/O.
The library is more or less doing
for(;;) {
timeout = calculate_min_timeout();
ret = select(...,timeout); //wait for a timeout event or filedescriptor events
if(ret > 0) {
process_readable_descriptors();
process_writable_descriptors();
}
process_timer_queue(); //scan through a timer priority queue and invoke callbacks
}
Because of the fact that the thread id inside the timer callback is the same as the creator thread I think that it is implemented somehow using signals.
When a signal is sent to a thread that thread's state is saved and the signal handler is called which then calls the event call back.
So the handler is called in the creator thread which is interrupted until the signal handler returns.
Maybe another thread waits for all timers using select() and if a timer expires it sends a signal to the thread the expired timer was created in.
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.