What is the proper way to get continuously processed data from a thread? - multithreading

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.

Related

Thread safety in Unity

In Unity, the thread cannot operate the object provided by UnityEngine like transform.position etc, which caused an exception that get_transform can only be called from the main thread.
However, these methods can be used in some async function like BeginReceive, so is there anyone can tell me why? The async function is not thread or sth else?
I try the code below:
void Start(){
AsyncCallback callback = new AsyncCallback (demo);
callback.BeginInvoke (null, null, null);
}
void demo(IAsyncResult result){
Debug.Log(Thread.CurrentThread.ManagedThreadId);
Debug.Log(gb.transform.position.ToString());
}
It does throw an exception when I run the code on Unity Editor. However, when I run this code on an Android phone directly, it didn't throw any exception and the code was performed correctly.
The log in applogcat shows that:
Line 13497: 02-20 14:37:49.973 31027 31697 I Unity : 3
Line 13501: 02-20 14:37:49.975 31027 31697 I Unity : (0.0, 0.0, 0.0)
So it seems that the function runs on another thread instead of main thread, so could anyone tell me why transform works on this situation?
Unity doesn't allow calling most API functions from threads other than the main thread, period. All of the event/message processing is actually done on the main thread.
The coroutine system based on IEnumerator is a bit of a hack and doesn't actually allow for multi-threading (keep in mind that even the .NET 4.5 async/await feature doesn't necessarily imply multithreaded execution either).
If calling the UnityEngine API works, you're on the main thread.
UI APIs aren't allowed to be called from a different thread than the UI one.
This simplifies how Unity works behind the scenes and actually makes it faster.
Some async methods are dispatched using an event loop and not a different thread. Just because a method is async it doesn't mean it gets to run on a different thread.
The most obvious example of this in Unity are Coroutines. They do run async, but on the main thread. This is possible because Unity adds all of to a list and executes them every frame.
You can call the Unity API from other threads, but NOT if you're running the game from within the Unity Editor. Release builds do not check which thread the call to the Unity API originated from. I assume they don't bother to avoid the performance hit.
I haven't tested this much myself though. The Unity documentation is quite clear that the API is not thread-safe. Therefore, definitely don't make any property assignments or calls that change the game state from other threads. Merely reading values might be OK, but it depends on the unknown internal caching behavior of UnityEngine, ie. hashtables/dictionaries would be bad for multi-threading.

How do I Yield() to another thread in a Win8 C++/Xaml app?

Note: I'm using C++, not C#.
I have a bit of code that does some computation, and several bits of code that use the result. The bits that use the result are already in tasks, but the original computation is not -- it's actually in the callstack of the main thread's App::App() initialization.
Back in the olden days, I'd use:
while (!computationIsFinished())
std::this_thread::yield(); // or the like, depending on API
Yet this doesn't seem to exist for Windows Store apps (aka WinRT, pka Metro-style). I can't use a continuation because the bits that use the results are unconnected to where the original computation takes place -- in addition to that computation not being a task anyway.
Searching found Concurrency::Context::Yield(), but Context appears not to exist for Windows Store apps.
So... say I'm in a task on the background thread. How do I yield? Especially, how do I yield in a while loop?
First of all, doing expensive computations in a constructor is not usually a good idea. Even less so when it's the "App" class. Also, doing heavy work in the main (ASTA) thread is pretty much forbidden in the WinRT model.
You can use concurrency::task_completion_event<T> to interface code that isn't task-oriented with other pieces of dependent work.
E.g. in the long serial piece of code:
...
task_completion_event<ComputationResult> tce;
task<ComputationResult> computationTask(tce);
// This task is now tied to the completion event.
// Pass it along to interested parties.
try
{
auto result = DoExpensiveComputations();
// Successfully complete the task.
tce.set(result);
}
catch(...)
{
// On failure, propagate the exception to continuations.
tce.set_exception(std::current_exception());
}
...
Should work well, but again, I recommend breaking out the computation into a task of its own, and would probably start by not doing it during construction... surely an anti-pattern for a responsive UI. :)
Qt simply uses Sleep(0) in their WinRT yield implementation.

WinForm Control BeginInvoke/Invoke Issue

I am trying to write a multithreaded WinForm in C++/CLI app using VS2012.
I know that only the UI thread can update a control and I have been using delegates and the invoke methods. However, I have run into a memory access issue when using BeginInvoke that I do not see when using Invoke.
Delegate Function:
public: delegate void pictureboxShowDelegate(int tChannelNumber,System::Windows::Forms::PictureBox^,System::Drawing::Bitmap^ colorImage);
Called Function:
void DrawCVImageShow(int tChannelNumber, System::Windows::Forms::PictureBox^ PBox, System::Drawing::Bitmap^ b)
{
if(PBox->InvokeRequired)
{
pictureboxShowDelegate^ d = gcnew pictureboxShowDelegate(this,&MyForm::DrawCVImageShow);
PBox->Invoke(d,tChannelNumber,PBox,b);
}
else
{
System::Drawing::Graphics^ graphics = PBox->CreateGraphics();
System::Drawing::RectangleF rect(0,0,(float)PBox->Width,(float)PBox->Height);
graphics->DrawImage(b,rect);
}
}
If called this way, it works with no problem.
If I substitute BeginInvoke for Invoke, I get an AccessViolationException.
Clearly, this has to do with the garbage collection of the parameters but I simply can't figure this one out.
Any help greatly appreciated.
Thanks
It sounds to me like whatever is calling DrawCVImageShow in the first place is Disposing the bitmap immediately after DrawCVImageShow returns.
If that's the case, there are a couple possiblities:
Make it so that DrawCVImageShow is the one responsible for Disposing the bitmap, not whatever calls DrawCVImageShow. (Simple solution, though probably not the best from an engineering solution: The thing that created the bitmap should generally be responsible for disposing it, and it makes DrawCVImageShow a less general method.)
Make a Clone of the bitmap, and dispose that one after it's been used. This is the more proper solution, in my opinion, but it does make things a little bit more complicated. You now need two versions of DrawCVImageShow, one that disposes the bitmap (for BeginInvoking), and one that doesn't (the method you have now). This also means you'll have two copies of the bitmap in memory when a BeginInvoke is needed; hopefully these bitmaps are not so large that this is an issue.

QPointer in multi-threaded programs

According to http://doc.qt.io/qt-5/qpointer.html, QPointer is very useful. But I found it could be inefficient in the following context:
If I want to show label for three times or do something else, I have to use
if(label) label->show1();
if(label) label->show2();
if(label) label->show3();
instead of
if(label) { label->show1();label->show2();label->show3(); }
just because label might be destroyed in another thread after label->show1(); or label->show2();.
Is there a beautiful way other than three ifs to get the same functionality?
Another question is, when label is destroyed after if(label), is if(label) label->show1(); still wrong?
I don't have experience in multi-threaded programs. Any help is appreciated. ;)
I think the only safe way to do it is to make sure you only access your QWidgets from within the main/GUI thread (that is, the thread that is running Qt's event loop, inside QApplication::exec()).
If you have code that is running within a different thread, and that code wants the QLabels to be shown/hidden/whatever, then that code needs to create a QEvent object (or a subclass thereof) and call qApp->postEvent() to send that object to the main thread. Then when the Qt event loop picks up and handles that QEvent in the main thread, that is the point at which your code can safely do things to the QLabels.
Alternatively (and perhaps more simply), your thread's code could emit a cross-thread signal (as described here) and let Qt handle the event-posting internally. That might be better for your purpose.
Neither of your approaches is thread-safe. It's possible that your first thread will execute the if statement, then the other thread will delete your label, and then you will be inside of your if statement and crash.
Qt provides a number of thread synchronization constructs, you'll probably want to start with QMutex and learn more about thread-safety before you continue working on this program.
Using a mutex would make your function would look something like this:
mutex.lock();
label1->show();
label2->show();
label3->show();
mutex.unlock()
As long as your other thread is using locking that same mutex object then it will prevented from deleting your labels while you're showing them.

How to run parallel codes using QT?

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();
}

Resources