I'm trying to write a multithreaded graphics manipulation program using Borland's C++ Builder 6 on WinXP SP3, but have run into (I think) a synchronisation issue, and can't figure out why.
Main Form (Form1) has a TPicture loaded from file. A copy of this is acquired by the thread via a Synchronize() call, and works fine. The thread does some work on the image, and in theory, it periodically updates the main Form image. The main Form also controls a machine, and is a 'First Resort' emergency stop, so blocking isn't an option. Everything is fine until the main Form gets hold of the working copy, or a copy of the working copy (sorry, but it's got to that) at which point the program hangs, and is only responsive to a 'program reset' from the IDE. A poor solution is to copy the working image to the Clipboard, and then, from the main Form, copy from the Clipboard to the main Form's image.
//Synchronization routines:
//----------------------------------------------------------------
`void __fastcall ImageRout::update()
{
Form1->Image9->Picture->Bitmap->Assign(Imgcopy);
//never returns
}
//----------------------------------------------------------------
void __fastcall ImageRout::getimage()
{
Imgcopy->Assign(Form1->Image9->Picture);
}
//----------------------------------------------------------------
//do the initialisation things... Then,
//(data is a struct, loaded with image data via a Synchronize() call)
Imgcopy=new Graphics::TBitmap;
Imgcopy->Width=data.width;
Imgcopy->Height=data.height; //size the bitmap
while(Imgcopy->Canvas->LockCount!=1)
{
Imgcopy->Canvas->TryLock();
} //have to Lock() the image or it gets lost... Somewhere
Synchronize(getimage); //works fine
//do some work on Imgcopy
//"By the book"- attempt 1
//(rate (=15) is a 'brake' to stop every alteration being displayed)
update_count++;
if(update_count>rate) //after a few iterations, update
{ //user interface
Synchronize(update); //fails: never returns from Synchronize call
update_count=0;
}
After a lot of failed attempts, I came up with this.
//in the thread...
update_count++;
if(update_count>rate)
{
EnterCriticalSection(&Form1->mylock1);
Form1->tempimage->Assign(Imgcopy); //tempimage is another bitmap,
InterlockedExchange(&Form1->imageready,1);//declared in the main Form
LeaveCriticalSection(&Form1->mylock1); //and is only ever accessed
update_count=0; //inside a critical section
}
//...and in the main Form....
if(imageready==1)
{
EnterCriticalSection(&mylock1);
Image9->Picture->Bitmap->Assign(tempimage); //Fails here
InterlockedExchange(&gotimage,1);
InterlockedExchange(&imageready,0);
LeaveCriticalSection(&mylock1);
}
So, in desperation.
//in the thread...
update_count++;
if(update_count>rate)
{
Synchronize(update);
EnterCriticalSection(&Form1->mylock1);
Form1->tempimage->Assign(Imgcopy);
Clipboard()->Assign(Imgcopy);
InterlockedExchange(&Form1->imageready,1);
LeaveCriticalSection(&Form1->mylock1); */
update_count=0;
}
//and in the main Form...
if(imageready==1)
{
EnterCriticalSection(&mylock1);
if (Clipboard()->HasFormat(CF_BITMAP))
{
Image9->Picture->Bitmap->Assign(Clipboard());
}
InterlockedExchange(&gotimage,1);
InterlockedExchange(&imageready,0);
LeaveCriticalSection(&mylock1);
}
This last attempt works, albeit relatively slowly, because of the Clipboard overhead, and it's a poor crutch, at best. I suspect the Clipboard is enforcing an otherwise failed synchronisation effort, but, as I said earlier, I can't fathom why. What can be the issue?
Thanks for your comments, Remy. They shook me out of a "tizzy" I'd got myself into whilst trying to solve the problem. I'd forgotten that Windows needs to move memory blocks around, and can't do this if locked them.
The initial problem of the Synchronize(update) call (code block 1 above) was caused by my still having the working copy (Imgcopy) locked (from inside the thread) during the call, preventing the main Form from subsequently accessing it. I suspect (but haven't investigated- that code has gone) the same root cause was at work in code block 2.
Locking every bitmap just prior to access, and unlocking immediately afterwards has solved this problem.
Peter O, thanks for your edit- I didn't realise there was so much overhead in my initial post.
Related
Ok I am trying to switch my Game Engine to multithreading. I have done the research on how to make it work to use OpenGL in multithreaded application. I have no problem with rendering or switching contexts. Let my piece of code explain the problem :) :
for (it = (*mIt).Renderables.begin(); it != (*mIt).Renderables.end(); it++)
{
//Set State Modeling matrix
CORE_RENDERER->state.ModelMatrix = (*it).matrix;
CORE_RENDERER->state.ActiveSubmesh = (*it).submesh;
//Internal Model Uniforms
THREAD_POOL->service.post([&]
{
for (unsigned int i = 0; i < CORE_RENDERER->state.ActiveShaderProgram->InternalModelUniforms.size(); i++)
{
CORE_RENDERER->state.ActiveShaderProgram->InternalModelUniforms[i]->Set( CORE_RENDERER->state.ModelMatrix);
}
CORE_RENDERER->state.ActiveSubmesh->_Render();
});
//Sleep(10);
}
I'll quickly explain what are the elements in the code to make my problem more clear. Renderables is a simple std::vector of elements with _Render() function which works perfectly. CORE_RENDERER->state is a struct holding information about current render state such as current material properties as well as current submesh ModelMatrix. So Matrix and Submesh are stored to state struct (I KNOW THIS IS SLOW, I'll probably change that in time :) ) The next piece of code is sent to THREAD_POOL->service which is actually boost::asio::io_service and has only one thread so it acts like a queue of rendering commands. The idea is that the main thread provides information about what to render and do frustum culling and other tests while an auxilary thread does actual rendering. This works fine, except there is a slight problem:
The code that is sent to thread pool starts to execute, but before all InternalModelUniforms are set and submesh is rendered the next iteration of Renderables is executed and both ModelMatrix and ActiveSubmesh are changed. The program doesn't crash but both informations change and some meshes are rendered some matrices are right others not which results in flickering image. Objects apear on frame and the next frame they are gone. The problem is only fixed if I enable that Sleep(10) function which makes sure that the code is executed before next iteration which obviously kills the idea of gaining preformance. What is the best possible solution for this? How can I send commands to the queue each with unique built in data? Maybe I need to implement my own queue for commands and a single thread without io_service?
I will continue my research as I know there is a way. The idea is right cause I get preformance boost as not a single if/else statement is processed by the rendering thread :) Any help or tips will really help!
Thanks!
Update:
After struggling for few nights I have created a very primitive model of communication between main thread and an Aux Thread. I created a class that represents a base command to be executed by aux thread:
class _ThreadCommand
{
public:
_ThreadCommand() {}
~_ThreadCommand() {}
virtual void _Execute() = 0;
virtual _ThreadCommand* Clone() = 0;
};
These commands that are childs of this class have _Execute() function to do whatever operation needs to be done. The main thread upon rendering fills a boost::ptr_vector of these commands While aux thread keeps on checking if there are any commands to process. When commands are found it copies entire vector to it's own vector inside _AuxThread and clears the original one. Commands are then executed by calling _Execute functions on each:
void _AuxThread()
{
//List of Thread commands
boost::ptr_vector<_ThreadCommand> _cmd;
//Infinitive loop
while(CORE_ENGINE->isRunning())
{
boost::lock_guard<boost::mutex> _lock(_auxMutex);
if (CORE_ENGINE->_ThreadCommands.size() > 0)
{
boost::lock_guard<boost::mutex> _auxLock(_cmdMutex);
for (unsigned int i = 0; i < CORE_ENGINE->_ThreadCommands.size(); i++)
{
_cmd.push_back(CORE_ENGINE->_ThreadCommands[i].Clone());
}
//Clear commands
CORE_ENGINE->_ThreadCommands.clear();
//Execute Commands
for (unsigned int i = 0; i < _cmd.size(); i++)
{
//Execute
_cmd[i]._Execute();
}
//Empty _cmd
_cmd.clear();
}
}
//Notify main thread that we have finished
CORE_ENGINE->_ShutdownCondition->notify_one();
}
I know that this is a really bad way to do it. Preformance is quite slower which I'm quite sure is because of all the copying and mutex locks. But at least the renderer works. You can get the idea of what I want to achieve but as I said I am very new to multithreading. What is the best solution for this scenario? Should I return back to ThreadPool system with asio::io_service? How can I feed commands to AuxThread with all values that must be sent to renderer to preform tasks in correct way?
First, a warning. Your "slight problem" is not slight at all. It is race condition, which is undefined behavior in C++, which, in turn, implies that anything could happen, including:
Everything renders fine
Image flickers
Nothing renders at all
It crashes on the last Saturday of every month. Or working fine on your computer and crashing on everyone's else.
Seriously, do not ever rely on UB, especially when writing library/framework/game engine.
Now about your question.
Lets leave aside any practical benefits of your approach and fix it first.
Actually, OpenGL implementation uses something very similar under the hood. Commands are executed asynchronously by the driver thread. I recommend you to read about their implementation to get some ideas on how to improve your design.
What you need to do, is to somehow "capture" the state at the time you post a rendering command. Simplest possible thing - copy the CORE_RENDERER->state into closure and use this copy to do the rendering. If state is large enough, it can be costly, though.
Alternative solution (and OpenGL goes that way) is to make every change in the state a command also, so
CORE_RENDERER->state.ModelMatrix = (*it).matrix;
CORE_RENDERER->state.ActiveSubmesh = (*it).submesh;
translates into
Matrix matrix = (*it).matrix;
Submesh submesh = (*it).submesh;
THREAD_POOL->service.post([&,matrix,submesh]{
CORE_RENDERER->state.ModelMatrix = matrix;
CORE_RENDERER->state.ActiveSubmesh = submesh;
});
Notice, however, that now you can't simply read CORE_RENDERER->state.ModelMatrix from your main thread, as it is changing in a different thread. You must first ensure that command queue is empty.
I have an application that continuously reads an image from a camera and displays this to a user. The user can adjust different sliders such as exposure and threshold to modify the image in real-time. I also do a bunch of calculations on this image afterwards which sometimes makes the GUI unresponsive, so I decided to use threads to divide the workload.
However, I can't get it to work properly, sometimes I get segmentation faults and a bunch of "assertion ` GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed" warnings when the slider values are changed or if I try to save the image (save button in my GUI), and the GUI sometimes stops updating the image or freezes so you can't move the sliders or push any buttons.
What I tried to do was to use the standard std::thread in C++, and connect it to the start button through a slot.
QObject::connect(btnStart, SIGNAL(clicked()), this, SLOT(RunStartThread()));
void MainMenu::RunStartThread(){
std::thread t1;
t1= std::thread(&MainMenu::Start,this);
t1.detach();
}
void MainMenu::Start() {
run = true;
window->mngr->ReadCalibration();
window->mngr->InitializeCameras();
while (run) {
window->mngr->CaptureImage();
window->mngr->ProcessImages();
UpdateLabels();
}
window->mngr->Stop();
}
When the user changes the slider values they change variables in my manager (mngr above) that captureImage and ProcessImages uses. I tried using a std::mutex lock/unlock when a variable was to be accessed, but it did not change anything. I've tried to find examples of how to do this online, but have yet to find something that has a continuous while-loop.
I'm a newbie when it comes to threads, so just tell me if I'm approaching this in the wrong way.
First for all for inter thread communication use singnals and slots. By default Qt connections do nice thread hopping between threads which lets to avoid complex synchronization.
Secondly you have three ways of using threads: QThread, QRunnable, QtConcurrent::Run (my favorite, since requires minimum amount of code).
In case QThread please do not subclass it! It is common design mistake.
Example:
SomeClass::~SomeClass()
{
SignalStop();
future.result();
}
void SomeClass::RunStartThread(){
future = QtConcurrent::run(this, &SomeClass::DoOnThread);
}
void SomeClass::DoOnThread()
{
while (ShouldContinueToRun()) {
QImage im1 = CaptureImage();
emit ImageCaptured(im1);
QImage im2 = ProcessImages(im1);
emit ImageProcessed(im2);
}
emit JobCompleted();
}
Please note that QObject::connect has last argument which defines how invocation of slot is performed if different thread is involved. See documentation of enumeration used for this argument.
So by default Qt detects if thread hopping is needed or not. Reading carefully about QObject::moveToThread should also help to understand the problem (note you can't move object to different thread if it has a parent).
I have a program that runs a least squares fit to some data. This procedure is run in a separate thread and controlled from a dialog box. This dialog box has a QPlainTextEdit that shows fitting updates and a final report.
The dialog was created in Qt Designer, the code is run into QtCreator and my Qt version is 4.8.1.
The problem I am running into is somewhat erratic. When I run the procedure a first time, everything is fine. Then if I run it again, sometimes the program crashes with the message
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
The program has unexpectedly finished.
I tracked the problem to a call to the clear() method of a QPlainTextEdit. Here is some code.
// Snippets of the class definition
class QLSQDialog : public QDialog, public Ui_QLSQDialog
{
Q_OBJECT
public:
QLSQDialog(QWidget *parent = 0);
(...)
void UpdateDisplay(const QString &msg, int iter, double norm); // Update values of chi, etc on displays
signals:
void Run(); // Signal to run a LSQ procedure
(...)
private slots:
void on_btnRun_clicked();
(...)
private:
void Enables(bool running); // Enable and disable features depending on running state of LSQ fit
(...)
};
// Snippets of the class implementation
QLSQDialog::QLSQDialog(QWidget *parent) : QDialog(parent)
{
setupUi(this); // Set up dialog
(...)
txtInfo->clear(); // txtInfo is a QPlainTextEdit created in Designer
(...)
}
void QLSQDialog::UpdateDisplay(const QString &msg, int iter, double norm)
{
lblChi->setText(QString::number(norm,'f',12));
if (iter >= 0) lblIt->setText(QString::number(iter));
txtInfo->appendPlainText(msg);
}
void QLSQDialog::on_btnRun_clicked()
{
txtInfo->clear(); // Offending line in second run
Enables(true);
emit Run();
}
void QLSQDialog::Enables(bool running)
{
bool Idle = !running;
bool HasReport = !txtInfo->document()->isEmpty();
(...)
btnReport->setEnabled(Idle && HasReport);
}
txtInfo is the QPlainTextEdit object. I call a txtInfo->clear() when the object is
created to show an empty text edit. When I click on a 'Run' tool button its default slot emits a Run signal that will start the new thread. The txtInfo QPlainTextEdit is updated in this thread until it finishes (in fact the thread emits a signal that is caught in the main application that in turn calls the UpdateDisplay).
If I click on the run button a second time, then I get the crash and the error. If I replace txtInfo->clear(), txtInfo->document()->clear(), by txtInfo->setPlainText("") or by txtInfo->document()->setPlainText("") the problem is the same (crash at second execution). Occasionally, but not frequently, I can run a few times (of the order of 10) before crashing.
Finally, if I comment out the txtInfo->clear() line, then I can run the routine as much as I tried (in one test I got tired after running it about 80 times).
My only (almost random) guess is that the problem is somehow related to the update from the thread (which emits a signal that is caught and in turn just calls the UpdateDisplay function). The reason I think so is that if I comment out the signals and just create a new button to call the UpdateDisplay with some bogus information, everything is fine.
A qApp->processEvents() before the offending line has no effect.
I am stuck here. Any ideas are welcome. For instance, is there any test I can do to verify that calling the clear() method is ok?
I finally tracked this problem down to a nasty memory leak in my code. I "repaired" the code but I am still a little bit puzzled by why the problem was happening.
Basically, I was creating a large vector<double> somewhere and passing its address to a function that called for a vector<double> * variable. The problem was that the original vector ceased to be before the function finished working with. Classic dumb mistake. Probably the QPlainTextEdit document was allocating space in the area where the vector<double> used to be: erratic behavior expected. But I would not expect a crash.
The vector was "read-only". The function using it, only read the values and made calculations stored somewhere else. Let's now assume that the plain text creates something in the memory previously addressed by the vector<double>. In this case, when I QPlainTextEdit::clear() the plain text document, the values previously pointed by the vector change and I would expect the calculations to be non sense. I would also accept a crash when the function access the now deceased pointer to vector<double>. But I would not expect the program to crash when I clear the text, which after all is a valid pointer.
Anyway, if anybody has a though, I'd be curious to know why the crash happens. But otherwise, the problem is gone once the leak was repaired. And of course, knowing the reason is absolutely no excuse to not repair the leak.
I'm having a strange problem with wxWidgets. I have the following code
MyFrame::OnDoSomeLongThing(...) {
progScreen = new wxProgressDialog(text,text,number,this,wxPD_AUTO_HIDE); // wxProgressDialog *progScreen is class member
doPartOfThing() // calls the update method at the end of it
....
doLastPartOfThing() // again calls update method that pushes value to 100/100
progScreen->Destroy();
}
MyFrame::update() {
progScreen->Update(newValue);
}
Now here's the thing. I can literally comment out the lines relating to progScreen, just let the process go without using a progress dialog, after all is said and done, my apps exits gracefully when I close the main window.
However, just the use of the progress dialog is somehow extending the life of the application. I've tried Destroy(), I've tried simply 'delete progScreen', and both, every time: I'll close the main frame, the process keeps running, and at some point exits with some astronomical number. The only thing I could think might be relevant, is that the doPartsOfThings methods may call boost::this_thread::sleep, because it involves waiting and whatnot down in my model class. But this shouldn't have anything to do with my problem. Or maybe it does... EDIT: I do want to emphasize that progScreen->Update() IS being called from the main (GUI) thread.
So I ask, am I using a wxProgressDialog correctly? If not, how should it be used?
Thanks for your help!
EDIT:
Well... it turns out that removing wxPD_AUTO_HIDE fixed the problem. I'm still not quite sure what the problem is, but the dialog even still behaves as before. App closes as expected.
I think that you need to override the wxApp method that closes the application so that it closes the wxProgressDialog object before it quits.
wxApp::OnExit
virtual int OnExit()
Override this member function for any processing which needs to be
done as the application is about to exit. OnExit is called after
destroying all application windows and controls, but before wxWidgets
cleanup. Note that it is not called at all if OnInit failed.
The return value of this function is currently ignored, return the
same value as returned by the base class method if you override it.
You will need something like, assuming progScreen is a public attribute of your frame
int myApp::OnExit()
{
(MyFrame*)(GetTopWindow())->progScreen->Destroy()
return wxApp::OnExit();
}
I have the following action which is executed when a certain
button is pressed in a Qt application:
#include <shape.h>
void computeOperations()
{
polynomial_t p1("x^2-x*y+1"),p2("x^2+2*y-1");
BoundingBox bx(-4.01, 4.01,-6.01,6.01,-6.01,6.01);
Topology3d g(bx);
AlgebraicCurve* cv= new AlgebraicCurve(p1,p2);
g.push_back(cv);
g.run();
//Other operations on g.
}
Topology3d(...), AlgebraicCurve(..), BoundingBox(...),
polynomial_t(...) are user defined types defined in the
corresponding header file .
Now for some values of p1 and p2, the method g.run() works perfectly.
Thus for some other values of p1 and p2, g.run() it is not
working anymore as the method gets blocked somehow and the
message "Application Not Responding" appears and I have to
kill the Application.
I would want to have the following behavior: whenever
g.run() is taking too long, gets blocked for some particular
values of p1, p2, I would want to display an warning box
using QMessageBox::Warning.
I try to do this with try{...} and catch{...}:
#include <shape.h>
class topologyException : public std::runtime_error
{
public:
topologyException::topologyException(): std::runtime_error( "topology fails" ) {}
};
void computeOperations()
{
try
{
polynomial_t p1("x^2-x*y+1"),p2("x^2+2*y-1");
BoundingBox bx(-4.01, 4.01,-6.01,6.01,-6.01,6.01);
Topology3d g(bx);
AlgebraicCurve* cv= new AlgebraicCurve(p1,p2);
g.push_back(cv);
g.run();
//other operations on g
throw topologyException();
}
catch(topologyException& topException)
{
QMessageBox errorBox;
errorBox.setIcon(QMessageBox::Warning);
errorBox.setText("The parameters are incorrect.");
errorBox.setInformativeText("Please insert another polynomial.");
errorBox.exec();
}
}
This code compiles, but when it runs it does not really
implement the required behavior.
For the polynomials for which g.run() gets blocked the error
message box code is never reached, plus for the polynomials
for which g.run() is working well, the error message box
code still is reached somehow and the box appears in the
application.
I am new to handling exceptions, so any help is more than
welcomed.
I think the program gets blocked somewhere inside g.run() so
it does not reach the exception, still I do not understand
what really happens.
Still I would want to throw this exception without going
into the code of g.run(), this function is implemented as
part of a bigger library, which I just use in my code.
Can I have this behavior in my program without putting any
try{...} catch{...} block statement in the g.run() function?
You cannot achieve what you want with the use of try-catch. if g.run() takes too much time or goes into an infinite loop, that doesn't mean an exception will be thrown.
What you can do is, you can move the operations that take a lot of time into another thread. Start that thread in your event handler and wait for it to finish in your main thread for a fixed amount of time. If it does not finish, kill that thread & show your messagebox.
For further reference, read QThread, Qt Thread Support
Thanks for the suggestions.
So I see how I should create the thread, something like:
class myopThread : public QThread
{
public:
void run();
};
Then I am rewriting the run() function and put all the operations that take a lot of time in it:
void myopThread::run()
{
polynomial_t p1("x^2-x*y+1"),p2("x^2+2*y-1");
BoundingBox bx(-4.01, 4.01,-6.01,6.01,-6.01,6.01);
Topology3d g(bx);
AlgebraicCurve* cv= new AlgebraicCurve(p1,p2);
g.push_back(cv);
g.run();
//other operations on g
exec();
}
Okay everything is clear so far, still I do not see how to "Start that thread in your event handler and wait for it to finish in your main thread for a fixed amount of time. If it does not finish, kill that thread & show your messagebox."
I mean start the thread in the event handler refers somehow at using the connect (..Signal, Slot..) still I do not see how exactly this is done. I have never used QThread before so it is more then new.
Thank you very much for your help,
madalina
The most elegant way to solve this that I know of is with a future value. If you haven't run across these before they can be quite handy in situations like this. Say you have a value that you'll need later on, but you can begin calculating concurrently. The code might look something like this:
SomeValue getValue() {
... calculate the value ...
}
void foo() {
Future<SomeValue> future_value(getValue);
... other code that takes a long time ...
SomeValue v = future_value.get();
}
Upon calling the .get() method of course, the value computed is returned, either by calling the function then and there or by retrieving the cache value calculated in another thread started when the Future<T> was created. One nice thing is that, at least for a few libraries, you can pass in a timeout parameter into the .get() method. This way if your value is taking too long to compute you can always unblock. Such elegant isn't usually achieved.
For a real life library, you might try looking into the library documented here. As I recall it wasn't accepted as the official boost futures library, but it certainly had promise. Good luck!