|
Animated Angular Meter |
Posted by Cody on Feb-21-2017 01:25 |
|
Hello Peter,
I have created a number of meters that I am animating by redrawing them in a loop checking the current value compared to the desired value.
There are up to 9 meters being animated at any one time and each is on it's own thread so that all 9 can update concurrently. The animation works and runs, but when the program is put through the Intel Inspector tool, it breaks saying there are data races within the code that draws the meters. Each time it's breaking at the AddText() function like so:
AngularMeter *am;
TextBox tb;
if(true)
{
tb = am->addText(rClient.right / 2, iValueOffset,
pGauge->formatValue(dValue, sTextBoxFormat),
"arialbd.ttf", iLabelSize, 0, Chart::Center);
}
else
{
int iValue = (int)dValue;
tb = am->addText(rClient.right / 2, iValueOffset,
pGauge->formatValue(iValue, sTextBoxFormat),
"arialbd.ttf", iLabelSize, 0, Chart::Center);
}
The code that handles drawing the chart works along these lines:
while(1)
{
while (current < target)
{
if(am)
delete am;
am = new AngularMeter(rClient.Width(), rClient.Height());
tb = am->addText(...);
am->addPointer(current)
pViewer->setChart(am);
current += animationSpeedValue
}
WaitForMultipleObjects(2, ghEvent, FALSE, INFINITE);
}
Each thread has its own instance of CChartViewer that is created when the meter starts, and each meter is updated roughly 30 times per second.
My question is this: is there special handling that needs to be done to animate multiple AngularMeters (and one LinearMeter) on multiple threads? The meters do run, but the Intel Inspector tool says there's a data race on the line that adds text. However if the animation is stopped and the meters are simply drawn at the target value, the tool no longer complains of a data race.
This is done in a C++ MFC application
Thanks for any help,
Cody |
Re: Animated Angular Meter |
Posted by Peter Kwan on Feb-22-2017 00:35 |
|
Hi Cody,
Internally, the addText just copies the text and the font and other parameters and store them in the BaseMeter object (the AngularMeter in your case). It does not really do anything else. Also, the code has been in use for more than 10 years in numerous multi-threading applications. (ChartDirector is also used in servers, which is commonly multi-threading.)
One possibility I can think of is that the issue is not really in addText, but in the arguments. You mentioned the code is like:
tb = am->addText(rClient.right / 2, iValueOffset,
pGauge->formatValue(dValue, sTextBoxFormat),
"arial.ttf", iLabelSize, 0, Chart::Center);
It is not clear what is rClient, pGauge, sTextBoxFormat or iLabelSize and where are they used. In particularly, pGauge is likely to be a BaseChart object. Like all BaseChart objects, each object can only be used in one thread. If pGauge in used in multiple threads, it will lead to a race condition. The other variables can also lead to race conditions if they can change in other threads. To eliminate the uncertainties, please hard code everything:
am->addText(10, 10, "10", "arial.ttf", 10, 0, Chart::Center);
If the hard coded parameters solve the problem, the issue may be is not in addText, but in the parameters.
If is also not clear in your code how tb is used. For testing, may be we can just remove it to make sure the TextBox cannot be used outside of the thread.
To further trouble-shoot the issue, you may consider to hard code everything just to make sure the parameters are not the cause of the problem, and to simplify the code to as simple as possible and to remove all unnecessary variables, just to make sure they cannot be used in another thread.
Regards
Peter Kwan |
Re: Animated Angular Meter |
Posted by Cody on Feb-22-2017 01:06 |
|
pGauge is a BaseChart object (AngularMeter). Each meter has its own instance of CChartViewer and AngularMeter and operates on only that instance.
The advice is appreciated, I had a feeling the problem was with one of the parameters (most likely the CRect rClient changing when the view/dialog is being created), but I was not sure and wanted to check that the TextBox was thread-safe also.
I did not get the chance to try hard-coding those values, due to a decision being made to multiplex the animation of the meters in one thread rather than have each meter running on its own thread.
Hopefully your advice will help someone else in the future
Thanks again,
Cody |
|