I am developing a simulator. I have chosen QT for the GUI. My project involves a lot of manipulation of data and I use QT just to plot my results.
My code structure is such that my main function contains a global object of my data, an object of the QT GUI and other objects for manipulating this data. I need to modify this data at every 30 ms. I have also attached a simplified version of my main file.
My problem is that I cannot call functions of my other objects (other than the GUI) before exiting the QT object. I have implemented timers in QT in isolation which plots the new data and works fine. All I want to do is call my ai and phySim object at a particular time interval independant of the QT object. I want these three objects to be completely independent.
world* _world;
int main(int argc, char *args[])
{
_world = new world();
gui *GUI; ///QT object
ai *AI;//object to manipulate data
phySim *sim;//object to manipulate data
/////////////////////////////////// this gets executed only when i close the QT gui
AI = new ai(_world);
AI->doSomething();
sim = new phySim(_world);
sim->updateWorld();
//////////////////////////////////////////////////////////////////////////////
QApplication app(argc,args);
GUI = new gui(_world);
GUI->show();
return app.exec();
}
Take a look at the Signals and Slots in Qt. Connect a "closed" signal that you emit when you close your GUI to a "startThread" slot. Have your AI and Simulation running in separate threads and if they need to interact, make use of signals/slots again.
You say you want the three objects to be "completely independent" -- then you should give each of them their own thread.
Maybe you should try not not run the app.exec(), but instead create a custom (almost) infinite loop, call processEvents() within that loop and your updateWorld() plus a wait of 30ms (or a little less, due to the function execution will take some ms). Drawing is then part of Qt (you should pass the instance of your simulator and add a render method (maybe best in pure OpenGL, as this can be passed through the Qt layer via a QGLWidget). Call that method within paint() or respectivly paintGL() for QGLWidget I hope this helps (a little), you should read QGLWidget doc
Note: You will have to write some wrappers in form of signals, calling your simulationObj methods, otherwise no UI interaction will be possible within Qt.
I was going to suggest overriding some event methods on QApplication but event loops can be tricky since you have some "child loops" http://labs.trolltech.com/blogs/2010/02/23/unpredictable-exec. In one of the 2009 Tech talks on there is a part that explains this too.
One approach is to separate your GUI a bit more by using a Client Server architecture. Your sim can be the server and Qt GUI the client. There are some nice samples in Qt using sockets.
Another approach is to use QTimer to update (or poll) your Sim. You might not even need threads.
void SomeGUI::SomeGUI(..)...
{
//Init sim
m_World = new world();
m_AI = new ai(m_World);
m_Sim = new phySim(m_World);
...
//Connect timer
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateWorld()));
timer->start(100); //or whatever interval works
...
}
void SomeGUI::updateWorld()
{
//Update sim state
m_AI->doSomething();
m_Sim->updateWorld();
updateGUI();
}
Related
The following functions and fields are part of the same class in a Visual Studio DLL. Data is continuously being read and processed using the run function on a thread. However, getPoints is being accessed in a Qt app on a QTimer. I don't wan't to miss a single processed vector, because it seems it could be skipping leading to jumpy data. What's the safest way to get the points to the updated version?
If possible I'd like an answer that uses the C++ standard library as I've been exploring mutex-es, but it still seems to lead to jumpy data.
vector<float> points;
// std::mutex ioMutex;
// function running on a thread
void run(){
while(running){
//ioMutex.lock()
vector<byte> data = ReadData()
points = processData(data);
//ioMutex.unlock()
}
}
vector<float> getPoints(){
return points;
}
I believe there is a mistake in your code. The while loop will consume all the process activity and will not allow proper functionality of other functions. In Qt, in such continuous loops, usually it is a good habit to use the following because it actually gives other process time to access the event buffer properly. If this dll is written in Qt, please add the following within the while loop
QCoreApplication::processEvents();
The safest (and probably easiest) way to deliver your points-data to the main thread is by calling qApp->postEvent() with an object of a custom QEvent-subclass that contains your vector<float> as a member-variable.
That will cause the event(QEvent *) method of (whatever Qt object you specified as the first argument to postEvent()) to be called from inside the main/GUI thread, and so you can override that method to read the vector<float> out of the QEvent-subclassed object and update the GUI with that data.
I have started database loading in non-GUI thread with QtCuncurrent::run.
In this nonGui thread I have to create QStandardItemModel* and after that I received model in GUI thread with
model = modelWatcher.result();
on QFutureWatcher finished() signal. It works pretty (UI is builded successfully), but itemChanged() signal is not emitted on item data changes (checkbox state changed). When I creates the model in GUI thread, there are no collisions. Connect works without assert fails:
bool ok = connect(model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(onFolderStateChanged(QStandardItem*)), static_cast<Qt::ConnectionType>(Qt::UniqueConnection));
Q_ASSERT(ok);
As I can see in that thread (there are no code samples and I misunderstood the main idea) I can't to create model (part of Qt5Gui) in nonGui thread. But it works for me! Ui is builded) Also I have to declare sended type with:
qRegisterMetaType<QStandardItemModel*>("QStandardItemModel*");
And my other sends like:
qRegisterMetaType<QList<QTreeWidgetItem*> >("QList<QTreeWidgetItem*>");
works good (though its also Qt5Gui part).
I dont understand how can I **get the model from nonGui thread with full functionality** like itemChanged signals?
Its something like emit mysignal(QStandardItemModel*); ?
In that case, why other tasks works fine without any emit`s ? including currentChanged signals etc.
When I send model from nonGui thread, some signals have been lost, because model pointer and related data is incorrect if I'm not mistaken. Also QStandardItemModel - is a part of Qt5Gui and its not threadsafe. It means, that model and view should be collected in GUI thread, and data must be sended from worker thread and binded to the model in GUI thread. Its not simple in my situation - I have big tree and I don't want to create my own struct for parsing the tree - but it is a "true way").
I'm using more simple decision - I just sends the parentItem pointer to the new model in GUI thread - and it works.
If anybody knows how to send tree structure from worker thread simple - please tell it in this thread)
In any case - using text-represented data transfer between threads - its more preferred method (like JSON/XML...any yourself representation, based on indexes of items, listed in ``QList>` etc...)
Have you tried this ?
bool ok = connect(model, SIGNAL(itemChanged(QStandardItem*)), this,
SLOT(onFolderStateChanged(QStandardItem*)),
static_cast<Qt::ConnectionType>(Qt::AutoConnection | Qt::UniqueConnection));
I am trying to do some opengl 1.0 animation in a CWnd window with 60 fps. I create a sub class of CWnd:
class COpenGLControl : public CWnd
{
...
}
I found if I use the build-in timer "setTimer()" and set it to fire on every 1000/60 ms, all the opengl commands were able to render correctly. However, If I implement my own timer using a separate thread, nothing is drawn. All I got was a black screen.
Is there a way to issue opengl commands from a different thread?
Even if you are not intending to issue GL calls from multiple threads, you have to take OpenGL's rules for threading into account: An OpenGL context can only be used by at most one thread at a time. (And, per thread, there can be at most one active GL context at any time). That does not mean that you cannot use the same context in multiple threads, or create it in one and use it in another, you just have to explicitely "hand over" the context from one thread to another.
I don't know if you use some further librariy for GL context handling, so I'm assuming you are using the native API of your OS - in this case wgl. The relevant function is wglMakeCurrent(). So, to hand over a context which is "current" in thread A to thread B, thread A must first call wglMakeCurrent(NULL,NULL) before thread B can get the context via wglMakeCurrent(someDC, myGLCtx). You can of course switch around a GL context as many times you like, but that will introduce a huge synchronization overhead and should be avoided.
From your comments:
Would work If I create the context also in the timer thread?
Yes, it would.
Just a side note: Creating is not the issue here at all, since creating a GL context does not automatically make it "current" to a thread - so you can just create it in thread A and afterwards make it current directly to thread B.
I'm new to multithread programming. I wrote this simple multi thread program with Qt. But when I run this program it freezes my GUI and when I click inside my widow, it responds that your program is not responding .
Here is my widget class. My thread starts to count an integer number and emits it when this number is dividable by 1000. In my widget simply I catch this number with signal-slot mechanism and show it in a label and a progress bar.
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
MyThread *th = new MyThread;
connect( th, SIGNAL(num(int)), this, SLOT(setNum(int)));
th->start();
}
void Widget::setNum(int n)
{
ui->label->setNum( n);
ui->progressBar->setValue(n%101);
}
and here is my thread run() function :
void MyThread::run()
{
for( int i = 0; i < 10000000; i++){
if( i % 1000 == 0)
emit num(i);
}
}
thanks!
The problem is with your thread code producing an event storm. The loop counts very fast -- so fast, that the fact that you emit a signal every 1000 iterations is pretty much immaterial. On modern CPUs, doing a 1000 integer divisions takes on the order of 10 microseconds IIRC. If the loop was the only limiting factor, you'd be emitting signals at a peak rate of about 100,000 per second. This is not the case because the performance is limited by other factors, which we shall discuss below.
Let's understand what happens when you emit signals in a different thread from where the receiver QObject lives. The signals are packaged in a QMetaCallEvent and posted to the event queue of the receiving thread. An event loop running in the receiving thread -- here, the GUI thread -- acts on those events using an instance of QAbstractEventDispatcher. Each QMetaCallEvent results in a call to the connected slot.
The access to the event queue of the receiving GUI thread is serialized by a QMutex. On Qt 4.8 and newer, the QMutex implementation got a nice speedup, so the fact that each signal emission results in locking of the queue mutex is not likely to be a problem. Alas, the events need to be allocated on the heap in the worker thread, and then deallocated in the GUI thread. Many heap allocators perform quite poorly when this happens in quick succession if the threads happen to execute on different cores.
The biggest problem comes in the GUI thread. There seems to be a bunch of hidden O(n^2) complexity algorithms! The event loop has to process 10,000 events. Those events will be most likely delivered very quickly and end up in a contiguous block in the event queue. The event loop will have to deal with all of them before it can process further events. A lot of expensive operations happen when you invoke your slot. Not only is the QMetaCallEvent deallocated from the heap, but the label schedules an update() (repaint), and this internally posts a compressible event to the event queue. Compressible event posting has to, in worst case, iterate over entire event queue. That's one potential O(n^2) complexity action. Another such action, probably more important in practice, is the progressbar's setValue internally calling QApplication::processEvents(). This can, recursively call your slot to deliver the subsequent signal from the event queue. You're doing way more work than you think you are, and this locks up the GUI thread.
Instrument your slot and see if it's called recursively. A quick-and-dirty way of doing it is
void Widget::setNum(int n)
{
static int level = 0, maxLevel = 0;
level ++;
maxLevel = qMax(level, maxLevel);
ui->label->setNum( n);
ui->progressBar->setValue(n%101);
if (level > 1 && level == maxLevel-1) {
qDebug("setNum recursed up to level %d", maxLevel);
}
level --;
}
What is freezing your GUI thread is not QThread's execution, but the huge amount of work you make the GUI thread do. Even if your code looks innocuous.
Side Note on processEvents and Run-to-Completion Code
I think it was a very bad idea to have QProgressBar::setValue invoke processEvents(). It only encourages the broken way people code things (continuously running code instead of short run-to-completion code). Since the processEvents() call can recurse into the caller, setValue becomes a persona-non-grata, and possibly quite dangerous.
If one wants to code in continuous style yet keep the run-to-completion semantics, there are ways of dealing with that in C++. One is just by leveraging the preprocessor, for example code see my other answer.
Another way is to use expression templates to get the C++ compiler to generate the code you want. You may want to leverage a template library here -- Boost spirit has a decent starting point of an implementation that can be reused even though you're not writing a parser.
The Windows Workflow Foundation also tackles the problem of how to write sequential style code yet have it run as short run-to-completion fragments. They resort to specifying the flow of control in XML. There's apparently no direct way of reusing standard C# syntax. They only provide it as a data structure, a-la JSON. It'd be simple enough to implement both XML and code-based WF in Qt, if one wanted to. All that in spite of .NET and C# providing ample support for programmatic generation of code...
The way you implemented your thread, it does not have its own event loop (because it does not call exec()). I'm not sure if your code within run() is actually executed within your thread or within the GUI thread.
Usually you should not subclass QThread. You probably did so because you read the Qt Documentation which unfortunately still recommends subclassing QThread - even though the developers long ago wrote a blog entry stating that you should not subclass QThread. Unfortunately, they still haven't updated the documentation appropriately.
I recommend reading "You're doing it wrong" on Qt Blog and then use the answer by "Kari" as an example of how to set up a basic multi-threaded system.
But when I run this program it freezes my GUI and when I click inside my window,
it responds that your program is not responding.
Yes because IMO you're doing too much work in thread that it exhausts CPU. Generally program is not responding message pops up when process show no progress in handling application event queue requests. In your case this happens.
So in this case you should find a way to divide the work. Just for the sake of example say, thread runs in chunks of 100 and repeat the thread till it completes 10000000.
Also you should have look at QCoreApplication::processEvents() when you're performing a lengthy operation.
I'm 100% new to threading, as a start I've decided I want to muck around with using it to update my physics in a separate thread. I'm using a third party physics engine called Farseer, here's what I'm doing:
// class level declarations
System.Threading.Thread thread;
Stopwatch threadUpdate = new Stopwatch();
//In the constructor:
PhysicsEngine()
{
(...)
thread = new System.Threading.Thread(
new System.Threading.ThreadStart(PhysicsThread));
threadUpdate.Start();
thread.Start();
}
public void PhysicsThread()
{
int milliseconds = TimeSpan.FromTicks(111111).Milliseconds;
while(true)
{
if (threadUpdate.Elapsed.Milliseconds > milliseconds)
{
world.Step(threadUpdate.Elapsed.Milliseconds / 1000.0f);
threadUpdate.Stop();
threadUpdate.Reset();
threadUpdate.Start();
}
}
}
Is this an ok way to update physics or should there be some stuff I should look out for?
In a game you need to synchronise your physics update to the game's frame rate. This is because your rendering and gameplay will depend on the output of your physics engine each frame. And your physics engine will depend on user input and gameplay events each frame.
This means that the only advantage of calculating your physics on a separate thread is that it can run on a separate CPU core to the rest of your game logic and rendering. (Pretty safe for PC these days, and the mobile space is just starting to get dual-core.)
This allows them to both physics and gameplay/rendering run concurrently - but the drawback is that you need to have some mechanism to prevent one thread from modifying data while the other thread is using that data. This is generally quite difficult to implement.
Of course, if your physics isn't dependent on user input - like Angry Birds or The Incredible Machine (ie: the user presses "play" and the simulation runs) - in that case it's possible for you to calculate your physics simulation in advance, recording its output for playback. But instead of blocking the main thread you could move this time-consuming operation to a background thread - which is a well understood problem. You could even go so far as to start playing your recording back in the main thread, even before it is finished recording!
there is nothing wrong with your approach in general. Moving time-consuming operations, such as physics engine calculations to a separate thread is often a good idea. However, I am assuming that your application includes some sort of visual representation of your physics objects in the UI? If this is the case you are going to run into problems.
The UI controls in Silverlight have thread affinity, i.e. you cannot update their state from within the thread you have created in the above example. In order to update their state you are going to have to invoke via the Dispatcher, e.g. TextBox.Dispatcher.Invoke(...).
Another alternative is to use a Silverlight BackgroundWorker. This is a useful little class that allows you to do time-consuming work. It will move your work onto a background thread, avoiding the need to create your own System.Threading.Thread. It will also provide events that marshal results back onto the UI thread for you.
Much simpler!