Having a bit of trouble wrapping my head around Qtimer this morning.
Here's the basic idea:
I have a QTimer that is started by clicking a button.
Once it is active, every 5 minutes it calls a function (let's call it start() ).
Start() calls a seperate function (call it work() )using QtConcurrent. Thus, it returns quickly, even though processing is still occuring.
Here's my problem:
I want to call work() a number of times, once after the other. My issue is that currently, it will call the work() function multiple times before it has finished processing, which, since it interfaces to hardware, doesn't work.
How should I go about this properly?
EDIT:
Here is the basic flow of the program:
User clicks startTimer().
StartTime() calls timer->start()
when the timer emits a signal, it calls Start()
Start() does some light UI stuff, then makes does
future = QtConcurrent::run(...work()...) //work takes a long time
watcher->setFuture(*future)
somehow (this is my issue), when work() is done, I want to call it again (4 times, to be exact)
If I understand correctly your question you want to avoid running the work() function in multiple threads simultaneously.
Use a QMutexLocker at the top of your work() function and add the corresponding QMutex to your class definition.
THis way the execution of the work() function will be blocked until the previous execution has finished.
If your work() function had an anomaly where it took 20 minutes for some reason, would you want to then run the 4 next work() callbacks as soon as possible...or still want them to be spaced out by 5 minutes despite the delay?
If what you want is really 5 minute intervals, then you should use a single-shot timer that is re-queued each time you complete a work item. This way, you don't have the potential of winding up with a big blocked up queue of QTimer messages that can flood in and run all at once:
http://doc.qt.io/qt-4.8/qtimer.html#singleShot-prop
Related
I have a small IDE for a modeling language I wrote, implemented in PyQt/PySide, and am trying to implement a code navigator that let's you jump to different sections in the file being edited.
The current implementation is: (1) connect to QPlainTextEditor.textChanged, (2) any time a change is made, (sloppily) parse the file and update the navigator pane
It seems to work OK, but I'm worried this could cause major performance issues for large files on slower systems, in particular if more stuff is connected to textChanged in the future.
My question: Has anybody here implemented a delayed reaction to events, so that multiple events (i.e. keystrokes) within a short period only trigger a single update (say once per second)? And is there a proper QT way of doing this?
Thanks,
Michael
You can try using timers if you want some "delay".
There would be 2 ways to use them (with different results).
One is only parse after no input has been done for a certain amount of time
NOTE: I only know C++ Qt but I assume the same things are valid for pyqt so this is kind of "pseudocode" I hope you get the concept though.
QTimer timer; //somewhere
timer.setSingleShot(true); //only fire once
connect(timer,QTimer::timeout(),OnTimerDone(...);
OnTextChanged(...)
{
timer.start(500); //wait 500ms
}
OnTimerDone(...)
{
DoStuff(...);
}
This will restart the timer every input, so when you call that and the timer is not done the timeout signal is not emitted. When no input is done for an amount of time the timer timeouts and you parse the file.
The second option would be to have a periodic timer running (singleShot(false)).
Just start the timer for like each second. and timeout will be called once a second. You can combine that with a variable which you set to true when the input changes and to false when the file is parsed. So you avoid parsing when nothing has changed.
In C++Qt you won't have to worry about multi-threading because the slot gets called in the GUI thread. I assume it is the same for python but you should probably check this.
I have a Qt application that launches two threads from the main thread at start up. Both these threads make network requests using distinct instances of the QNetworkAccessManager object. My program keeps crashing about 50% of the times and I'm not sure which thread is crashing.
There is no data sharing or signalling occurring directly between the two threads. When a certain event occurs, one the threads signals the main thread, which may in turn signal the second thread. However, by printing logs, I am pretty certain the crash doesn't occur during the signalling.
The structure of both threads is as follows. There's hardly any difference between the threads except for the URL etc.
MyThread() : QThread() {
moveToThread(this);
}
MyThread()::~MyThread() {
delete m_manager;
delete m_request;
}
MyThread::run() {
m_manager = new QNetworkAccessManager();
m_request = new QNetworkRequest(QUrl("..."));
makeRequest();
exec();
}
MyThread::makeRequest() {
m_reply = m_manager->get(*m_request);
connect(m_reply, SIGNAL(finished()), this, SLOT(processReply()));
// my log line
}
MyThread::processReply() {
if (!m_reply->error()) {
QString data = QString(m_reply->readAll());
emit signalToMainThread(data);
}
m_reply->deleteLater();
exit(0);
}
Now the weird thing is that if I don't start one of the threads, the program runs fine, or at least doesn't crash in around 20 invocations. If both threads run one after the other, the program doesn't crash. The program only crashes about half the times if I start and run both the threads concurrently.
Another interesting thing I gathered from logs is that whenever the program crashes, the line labelled with the comment my log line is the last to be executed by both the threads. So I don't know which thread causes the crash. But it leads me to suspect that QNetworkAccessManager is somehow to blame.
I'm pretty blank about what's causing the crash. I will appreciate any suggestions or pointers. Thanks in advance.
First of all you're doing it wrong! Fix your threading first
// EDIT
From my own experience with this pattern i know that it may lead to many unclear crashes. I would start from clearing this thing out, as it may straighten some things and make finding problem clear. Also I don't know how do you invoke makeRequest. Also about QNetworkRequest. It is only a data structure so you don't need to make it on heap. Stack construction would be enough. Also you should remember (or protect somehow) from overwriting m_reply pointer. Do you call makeRequest more than once? If you do, then it may lead to deleting currently processed request after previous request finished.
What does happen if you call makeRequest twice:
First call of makeRequest assigns m_reply pointer.
Second call of makeRequest assigns m_reply pointer second time (replacing assigned pointer but not deleting pointed object)
Second request finishes before first, so processReply is called. deleteLater is queued at second
Somewhere in eventloop second reply is deleted, so from now m_reply pointer is pointing at some random (deleted) memory.
First reply finishes, so another processReply is called, but it operates on m_reply that is pointing a garbage, so every call at m_reply produces crash.
It is one of possible scenarios. That's why you don't get crash every time.
I'm not sure why do you call exit(0) at reply finish. It's also incorrect here if you use more then one call of makeRequest. Remember that QThread is interface to a single thread, not thread pool. So you can't call start() second time on thread instance when it is still running. Also if you're creating network access manager in entry point run() you should delete it in same place after exec(). Remember that exec() is blocking, so your objects won't be deleted before your thread exits.
I have an interesting problem. Working on a C++ project with Qt. Cross-plat project but developing on Win.
I have a C style callback function. It needs to be C style, I have no choice about it.
The work done in that C style callback function is significant and time sensitive. Therefore I have some Qthread threads help with the workload.
I am not using the run scheme with Qt thread, rather I use QThreads as explained at the bottom of the QThread docs. http://qt-project.org/doc/qt-5.0/qthread.html#wait
For the sake of clarity, I am using QThread as such:
QThread *thread = new QThread;
Worker *worker = new Worker;
worker->moveToThread(thread);
thread->start();
QMetaObject::invokeMethod(worker, "doWork", Qt::QueuedConnection);
The threads are made at start of application and are fed with QMetaObject::invokeMethod.
The challenge is to not have the C callback function do "anything" (in an efficient way) until the QThread threads have finished their work. I'd like to make the callback function wait in such a way that it does not compete for the cpu with the worker threads (so no busy dummy loop). I could also use something like sleep() but this is not efficient because if the threads finish 'early' there will be wasteful sleeping. I thought of sending a signal from the workers but the problem is that my callback is a C function so I don't see how it can catch a Qt signal.
The question is quiet old, but it came up in "related questions". And as this question is interesting and the answer can be useful to Qt users, i've decided to give a detailed answer.
To do wait on a function in a different QThread to finish, multiple strategies are possible:
Use Qt::BlockingQueuedConnection.
Use a naive while(anAtomicBoolean){} loop.
Use a somewhat more clever while(anAtomicBoolean){QThread::yieldCurrentThread();} loop.
Use a QWaitCondition.
Use a QSemaphore.
Strategies 2 and 3 look like bad ideas as the waiting thread will have to be active while waiting to check the loop condition. Strategy 3 has however the advantage to release CPU time for other threads and processes.
The 3 other strategies have the advantage of putting the thread to rest while waiting and should be quite equivalent. However solution 1 and 4 does not allow you (or at least easily) to run multiple workers in different threads at the same time. So the best solution would be to go with semaphores.
QSemaphore semaphore(2)
worker1.sem = &semaphore;
worker2.sem = &semaphore;
semaphore.acquire(2);
QMetaObject::invokeMethod(&worker1, "doWork", Qt::QueuedConnection);
QMetaObject::invokeMethod(&worker2, "doWork", Qt::QueuedConnection);
semaphore.acquire(2); // each worker release(1) when done
semaphore.release(2);
To prove my claim I have made a little benchmark (I will make the code available later if someone is interested). I used QueryThreadCycleTime() to get the number of cycle consumed by the waiting thread. Like this:
QueryThreadCycleTime(hThread, &start);
QMetaObject::invokeMethod(&worker, "doWork", Qt::BlockingQueuedConnection);
QueryThreadCycleTime(hThread, &stop);
The benchmark results are presented in the graph below:
Okay, consider such aproach. Let your callback function do nothing except setting some flag (or incrementing some counter) that is global and shows if (or how many times) your function was called. Then imlement class inherited from QObject (to have slots). You subscribe it to thread finished signal. When signal is emitted you just call another function (with logic of your callback-function) so much times it was called by lib. Will it work?
If you have thread "in hand", and you're completly sure that thread will quit itself after finishing work.
http://qt-project.org/doc/qt-4.8/qthread.html#wait
BUT!
If you don't want your thread to quit, and just want to wait until worker emit some singal you may do something like that:
QEventLoop loop;
connect(worker, SIGNAL(workFinished()), &loop, SLOT(quit()));
QMetaObject::invokeMethod(worker, "doWork", Qt::QueuedConnection);
loop.exec();
I always use QObject::connect() in all my applications but it is not clear to me its effect when my program is currently inside a function. Suppose I have the following code:
void main() {
//other stuffs here
QObject::connect(xxx,SIGNAL(yyy()),this,SLOT(zzz());
}
void aFunction()
{
//a bunch of codes here
//i am here when suddenly signal is emitted from QObject::connect();
//another bunch of codes here
}
I assume that when the signal is emitted, QObject::connect leaves the function "aFunction()" to execute "zzz()". What will happen to the remaining codes in the "aFunction()"
Thanks.
I can understand the confusion, coming from procedural to event based programming gives me same experience like you do now.
Short answer:
in non multi threaded environment, slot zzz() will be executed after aFunction() finishes. In fact, the signal probably gets emitted after aFunction finishes.
in multi threaded env., same thing but it is "after some time", not after.
Key to understanding this is Event Loop. QApplication::exec() runs a forever loop polling for event. New event is then handled, signals get emitted and depending on the fifth argument of QObject::connect which is a Qt::ConnectionType, ultimately runs the connected slot. You can read QObject documentation for more detail..
So your aFunction probably gets called after some signal, so after it is finished, it's back to event loop again, then your 'suddenly emitted' signal actually gets emitted and zzz is executed.
Even in multi threading environment, inter thread signals and slots work with Qt::QueuedConnection which basically just posts the emitted signal to corresponding thread so that when that thread's event loop come around to process it - it will be executed sequentially as well.
Ultimately what you will have to remember is that this Turing Machine called computers is executing sequences of codes, whether it's semi paralel (e.g time sharing, pipelining) or truly paralel (e.g multi cores, multi cpu) the part where codes get sent (or distributed? or fetched?) to its execution will always run in sequences or in one or more ways have to be simulated to be sequential so that no code is executed twice in multiple execution node.
There is no "suddenly"
A while ago I wrote a little RAII class to wrap the setOverrideCursor() and restoreOverrideCursor() methods on QApplication. Constructing this class would set the cursor and the destructor would restore it. Since the override cursor is a stack, this worked quite well, as in:
{
CursorSentry sentry;
// code that takes some time to process
}
Later on, I found that in some cases, the processing code would sometimes take a perceptible time to process (say more than half a second) and other times it would be near instantaneous (because of caching). It is difficult to determine before hand which case will happen, so it still always sets the wait cursor by making a CursorSentry object. But this could cause an unpleasant "flicker" where the cursor would quickly turn from the wait cursor to the normal cursor.
So I thought I'd be smart and I added a separate thread to manage the cursor override. Now, when a CursorSentry is made, it puts in a request to the cursor thread to go to the wait state. When it is destroyed it tells the thread to return to the normal state. If the CursorSentry lives longer than some amount of time (50 milliseconds), then the cursor change is processed and the override cursor is set. Otherwise, the change request is discarded.
The problem is, the cursor thread can't technically change the cursor because it's not the GUI thread. In most cases, it does happen to work, but sometimes, if I'm really unlucky, the call to change the cursor happens when the GUI thread gets mixed in with some other X11 calls, and the whole application gets deadlocked. This usually only happens if the GUI thread finishes processing at nearly the exact moment the cursor thread decides to set the override cursor.
So, does anyone know of a safe way to set the override cursor from a non-GUI thread. Keep in mind that most of the time, the GUI thread is going to be busy processing stuff (that's why the wait cursor is needed after all), so I can't just put an event into the GUI thread queue, because it won't be processed until its too late. Also, it is impractical to move the processing I'm talking about to a separate thread, because this is happening during a paint event and it needs to do GUI work when its done (figuring out what to draw).
Any other ideas for adding a delay to setting the override cursor would be good, too.
I don't think there is any other way besides a Signal-Slot connection going to the GUI thread followed by a qApp->processEvents() call, but like you said, this would probably not work well when the GUI thread is tied up.
The documentation for QCoreApplication::processEvents also has some recommended usages with long event processing:
This function overloads processEvents(). Processes pending events for
the calling thread for maxtime milliseconds or until there are no more
events to process, whichever is shorter.
You can call this function
occasionally when you program is busy doing a long operation (e.g.
copying a file).
Calling this function processes events only for the
calling thread.
If possible break up the long calls in the paint event and have it periodically check to see how long it has been taking. And in any of those checks, have it set the override cursor then from in the GUI Thread.
Often a QProgressBar can go a long way to convey the same information to the user.
Another option that could help quite a bit would be to render outside of the GUI thread onto a QImage buffer and then post it to the GUI when it is done.